这两种对象创建方式之间有区别吗?
new MyClass() { Id = 1,Code = "Test" };
要么
MyClass c = new MyClass(); c.Id = 1; c.Code = "Test";
什么更快?我假设2之间没有区别.
解决方法
第二个可能几乎肯定会更快,因为从逻辑上讲,涉及的任务较少.在第一种情况下,代码实际上等同于:
MyClass tmp = new MyClass() tmp.Id = 1; tmp.Code = "Test"; MyClass c = tmp;
当您声明一个新变量时,JIT编译器很可能会忽略它们 – 如果您使用对象初始化程序分配给现有变量,它将无法执行此操作.
编辑:我刚刚尝试使用和不使用优化进行编译,在这个“新变量”的情况下,如果它正在优化,C#编译器会忽略这两个.否则它没有(但JIT仍然可以).在“重新分配”的情况下,它可以产生可观察到的差异,因此我不希望进行相同的优化.我没有检查过.
我会非常惊讶地看到它实际上产生了显着差异的情况,所以我选择了更具可读性的选项,IMO是第一个.
编辑:我认为人们可能对基准测试感兴趣,表明它有所作为.这是一个故意可怕的代码,使隐藏的额外任务变慢 – 我已经创建了一个大的,可变的结构. Urgh.无论如何…
using System; using System.Diagnostics; struct BigStruct { public int value; #pragma warning disable 0169 decimal a1,a2,a3,a4,a5,a6,a7,a8; decimal b1,b2,b3,b4,b5,b6,b7,b8; decimal c1,c2,c3,c4,c5,c6,c7,c8; decimal d1,d2,d3,d4,d5,d6,d7,d8; #pragma warning restore 0169 } class Test { const int Iterations = 10000000; static void Main() { Time(NewVariableObjectinitializer); Time(ExistingVariableObjectinitializer); Time(NewVariableDirectSetting); Time(ExistingVariableDirectSetting); } static void Time(Func<int> action) { Stopwatch stopwatch = Stopwatch.StartNew(); action(); stopwatch.Stop(); Console.WriteLine("{0}: {1}ms",action.Method.Name,stopwatch.ElapsedMilliseconds); } static int NewVariableObjectinitializer() { int total = 0; for (int i = 0; i < Iterations; i++) { BigStruct b = new BigStruct { value = i }; total += b.value; } return total; } static int ExistingVariableObjectinitializer() { int total = 0; BigStruct b; for (int i = 0; i < Iterations; i++) { b = new BigStruct { value = i }; total += b.value; } return total; } static int NewVariableDirectSetting() { int total = 0; for (int i = 0; i < Iterations; i++) { BigStruct b = new BigStruct(); b.value = i; total += b.value; } return total; } static int ExistingVariableDirectSetting() { int total = 0; BigStruct b; for (int i = 0; i < Iterations; i++) { b = new BigStruct(); b.value = i; total += b.value; } return total; } }
结果(使用/ o / debug-):
NewVariableObjectinitializer: 3328ms ExistingVariableObjectinitializer: 3300ms NewVariableDirectSetting: 1464ms ExistingVariableDirectSetting: 1491ms
我有些惊讶于NewVariableObjectinitializer版本比直接设置版本慢……看起来C#编译器没有像它对引用类型那样优化这种情况.我怀疑在价值类型方面有一些微妙的东西会阻止它.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。