我在Java中实现了一个GapBuffer列表,我无法弄清楚为什么它会受到这样的性能损失.用C#编写的类似代码按预期运行:插入到列表中间的速度比C#的List实现要快得多.但Java版本表现得很奇怪.
以下是一些基准信息:
Adding/removing 10,000,000 items @ the end of the dynamic array...
ArrayList: 683 milliseconds
GapBufferList: 416 milliseconds
Adding/removing 100,000 items @ a random spot in the dynamic array...
- ArrayList add: 721 milliseconds
- ArrayList remove: 612 milliseconds
ArrayList: 1333 milliseconds
- GapBufferList add: 1293 milliseconds
- GapBufferList remove: 2775 milliseconds
GapBufferList: 4068 milliseconds
Adding/removing 100,000 items @ the beginning of the dynamic array...
ArrayList: 2422 milliseconds
GapBufferList: 13 milliseconds
Clearly, the GapBufferList is the better option.
Run Code Online (Sandbox Code Playgroud)
如您所见,当您插入列表的开头时,间隙缓冲区的行为与预期相同:它比ArrayList好很多很多倍.但是,当在列表中的随机位置插入和移除时,间隙缓冲区具有奇怪的性能损失,我无法解释.更奇怪的是,从GapBufferList中删除项目比向其添加项目要慢 - …
首先,一些背景信息:
我正在为学校项目编写一个编译器.它已经在工作,我正在花费大量精力修复和/或优化它.我最近遇到的一个问题是,leave
当我调用以下任何成员方法时,我发现ILGenerator对象会生成一条额外的指令:
BeginCatchBlock()
BeginExceptFilterBlock()
BeginFaultBlock()
BeginFinallyBlock()
EndExceptionBlock()
Run Code Online (Sandbox Code Playgroud)
所以,你通过调用启动一个try语句BeginExceptionBlock()
,添加一些catch子句BeginCatchBlock()
,可能添加一个finally子句BeginFinallyBlock()
,然后用EndExceptionBlock()
.结束受保护的代码区域.
我列出的方法自动生成一条leave
指令,该指令分支到try语句后的第一条指令.出于两个原因,我不想要这些.一,因为它总是生成一个未优化的leave
指令,而不是一条leave.s
指令,即使它只分支两个字节.还有两个,因为你无法控制离开指令的去向.
所以,如果你想分支到代码中的其他位置,你必须添加一个编译器生成的局部变量,根据你想要进入try语句的位置来设置它,让EndExceptionBlock()
自动生成leave
指令,然后在try块下面生成一个switch语句.或者,您可以在调用前面的方法之前自己发出一个leave
或leave.s
指令,导致一个丑陋且无法访问的额外5个字节,如下所示:
L_00ca: leave.s L_00e5
L_00cc: leave L_00d1
Run Code Online (Sandbox Code Playgroud)
这两个选项对我来说都是不可接受的.有没有办法阻止自动生成leave
指令,或者是否有任何其他方式来指定受保护区域而不是使用这些方法(这些方法非常烦人且实际上没有记录)?
编辑注意:C#编译器本身就是这样做的,所以并不是说有充分的理由强迫它在我们身上.例如,如果您有.NET 4.5 beta,请反汇编以下代码并检查它们的实现:(内部添加异常块)
public static async Task<bool> TestAsync(int ms)
{
var local = ms / 1000;
Console.WriteLine("In async call, before await " + local.ToString() + "-second delay.");
await System.Threading.Tasks.Task.Delay(ms);
Console.WriteLine("In async call, after await " + local.ToString() …
Run Code Online (Sandbox Code Playgroud) 我写了下面的测试代码,尽管我很确定会发生什么:
static void Main(string[] args)
{
Console.WriteLine(Test().ToString());
Console.ReadKey(false);
}
static bool Test()
{
try
{
try
{
return true;
}
finally
{
throw new Exception();
}
}
catch (Exception)
{
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
果然,该程序向控制台写了"False".我的问题是,最初返回的真实情况会发生什么?有没有办法获得这个值,如果可能的话,在catch块中,或者如果不是,在原始finally块中?
只是为了澄清,这仅用于教育目的.我永远不会在实际程序中制作这样一个复杂的异常系统.
查看Java虚拟机规范和编译代码,告诉我们如何在java中实现"synchronized"块.以下代码:
public void testSync()
{
Object obj = getSomeObject();
synchronized (obj) { doSomething(); }
}
Run Code Online (Sandbox Code Playgroud)
...大致相当于这个伪代码:
public void testSync()
{
Object obj = getSomeObject();
Object __temp = obj;
monitorenter __temp;
try { doSomething(); }
finally { monitorexit __temp; }
}
Run Code Online (Sandbox Code Playgroud)
......有一个例外.
出于某种原因,异常表显示两个finally处理程序.例如:
Exception table:
from to target type
12 20 23 any
23 25 23 any
Run Code Online (Sandbox Code Playgroud)
第一个处理程序是我期望的,但第二个处理程序实际上是第一个处理程序的finally块,如果它捕获异常,它会执行相同的处理程序.您可以通过以下方式将其可视化:
try { doSomething(); }
finally { beginTry: try { monitorexit __temp; } finally { goto beginTry; } }
Run Code Online (Sandbox Code Playgroud)
有谁知道这是为什么?如果它只是finally块,则表中的第二个条目不会出现.此外,如果它已经被抛出异常,我看不出任何可能的理由想要再次执行finally块. …
在最新版本的.NET框架4.5版本中,MethodBuilder类有一个调用的方法SetMethodBody
,我相信这正是我所看到的作为使用ILGenerator的替代方法(这种方法很烦人,而且很奇怪).文档可以在这里找到,虽然因为.NET 4.5还没有出来,所以没有完全记录.我可以提供除了两个参数之外的所有参数,但其余的我需要帮助.
我不明白的第一个是byte[] localSignature
第三个论点.MSDN声明它是"包含序列化局部变量结构的字节数组.如果方法没有局部变量,则指定null." 麻烦的是,就是这样,我无法找到"序列化局部变量签名"的格式.我试过查看ECMA-335规范,但我发现的是如何在未组装的CIL中指定局部变量.如果有人能帮我解决这个问题,我将不胜感激.
此外,最后一个参数是IEnumerable<int> tokenFixups
,"表示il中偏移的值的集合,每个值指定可以修改的标记的开头.如果方法没有必须修改的标记,则指定null.".我怀疑我不需要使用这些,但我想知道它们是什么.
谢谢,布兰登
我在C#程序中有以下简单的等式将数字转换为结果值:
sectorSize = 1 << sectorShift;
Run Code Online (Sandbox Code Playgroud)
是否有某种反向操作可以让我走另一条路?
sectorShift = ???
Run Code Online (Sandbox Code Playgroud)
我知道你可以实现一个循环,但这有点过分.我以前从来没有这样做,所以我不知道,我在网上找不到任何关于它的东西.当sectorSize是2的幂时,我需要的等式只需要产生有效的结果; 域名的其余部分可以为我所关心的所有人下地狱.
(注意:我已经问过这个问题,但答案是针对Java的,所以我问C#和.NET框架的问题.这不是重复的.)
我一直在使用这种模式,但我最近才开始认为这样做可能不太好.基本上,我使用这种模式的一些变体:
public class SampleAsync
{
public SampleAsync() { }
private bool completed;
public void Start()
{
var worker = new BackgroundWorker();
worker.DoWork += (sender, e) => {
//... do something on a different thread
completed = true;
};
worker.RunWorkerAsync();
}
public void Update()
{
if (!completed) return;
//... do something else
}
}
Run Code Online (Sandbox Code Playgroud)
*用户负责确保Start
只调用一次.Update
随时随地被召唤.
我一直认为这在C#/ .NET框架中是线程安全的,因为即使没有严格的同步,我也只能设置completed
为true.一旦被观察到true
,它将不会重置为false
.它在构造函数中初始化为false,根据定义,它是线程安全的(除非你在其中做了一些愚蠢的事情).那么,以这种方式使用不可复制的标志是否安全?(如果是这样,它甚至可以提供任何性能优势吗?)
谢谢
我正在一个网站上工作,我想到如果我把页面上的CSS规则随机化为一个笑话会有多么有趣.(不仅仅是元素的样式,而是CSS规则本身,因为网站有很多动态创建的元素.)每次加载页面时,结果都会完全不同,而且大多数都看起来很糟糕.所以我的问题有两个部分:
使用JavaScript/JQuery,您如何以编程方式获取所有CSS规则的列表?作为一种字典,规则与选择器配对.
然后,在您分解列表并将每个规则随机分配给不同的选择器之后,如何删除以前的规则并替换为您自己的规则?
注意:我的意思是,使用JavaScript/JQuery,如何在客户端随机化规则,而不仅仅是单个CSS文件.
我正在努力学习C++.在进行实验时,我输入以下代码,不要指望它能够工作,但希望它会:
int one = 1, two = 2;
one, two = two, one;
cout << "one = " << one << "\n";
cout << "two = " << two << "\n";
Run Code Online (Sandbox Code Playgroud)
令我感到鼓舞的是,编译器没有抱怨,因为这是我喜欢python的主要特性之一,我所学过的大多数编程语言都不匹配 - 在分配之前评估多个表达式的能力结果没有使用临时变量.但是,当我运行它时,我发现这段代码似乎无效.
玩了一下之后,我发现变量two
实际上已经设置了 - 所以,如果我运行这段代码:
one, two = 3, 4;
Run Code Online (Sandbox Code Playgroud)
two
将等于3,但one
不会改变.所以我的问题是,编译器在这个语句中究竟做了什么?我无法为我的生活弄明白.
谢谢,布兰登
我正在研究一个派生自UserControl
该类的类.此类添加的属性[Browsable(false)]
和[EditorBrowsable(EditorBrowsableState.Never)]
该事件TextChanged
是从继承的Control
类.
我的新控制与a相当TabPage
; 它在另一个可以与之相当的类中使用TabControl
.这很重要的原因是因为这意味着我需要控件的用户才能访问此事件.在.NET反射器中,我们看到TabPage
控件(继承自Panel
,也添加了这两个属性)使用以下代码"覆盖"这两个属性:
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
public event EventHandler TextChanged;
Run Code Online (Sandbox Code Playgroud)
我把它复制到我的项目中,据我所知,它可以正常工作,但编译器给了我一个警告:"'System.Windows.Forms.Frameset.FunctionPanel.TextChanged'隐藏了继承的成员'System.Windows.Forms. UserControl.TextChanged'.如果想要隐藏,请使用new关键字." 我不想隐藏旧的TextChanged事件; 我只是想删除该Browsable(false)
属性.虽然隐藏旧事件似乎可以在表面上完成工作,但这似乎是一种丑陋而迂回的做法.有没有办法在不隐藏旧事件的情况下做到这一点?如果没有,有没有办法让编译器停止给我一个警告?
在此先感谢,布兰登
c# ×5
.net ×3
cil ×2
java ×2
.net-4.5 ×1
asynchronous ×1
bit-shift ×1
c++ ×1
collections ×1
css ×1
events ×1
javascript ×1
jquery ×1
jvm ×1
performance ×1
return ×1
synchronized ×1
syntax ×1
try-catch ×1
try-finally ×1
winforms ×1