.net net中的结构构造函数:有开销吗?
关于使用结构构造函数;这两个代码块的性能相等吗 与构造器一起: Dim pt As Point For i As Integer = 1 To 1000 pt = New Point(i, i) Next Dim pt As Point For i As Integer = 1 To 1000 pt.X = i pt.Y = i Next 变暗pt为点 对于i,整数=1到1000 pt=新点(i,i) 下一个 无构造函数: Dim pt As Point For i As Integer = 1 To 1000 pt = New Point(i, i) Next Dim pt As Point For i As Integer = 1 To 1000 pt.X = i pt.Y = i Next 变暗pt为点 对于i,整数=1到1000 pt.X=i pt.Y=i 下一个.net net中的结构构造函数:有开销吗?,.net,structure,.net,Structure,关于使用结构构造函数;这两个代码块的性能相等吗 与构造器一起: Dim pt As Point For i As Integer = 1 To 1000 pt = New Point(i, i) Next Dim pt As Point For i As Integer = 1 To 1000 pt.X = i pt.Y = i Next 变暗pt为点 对于i,整数=1到1000 pt=新点(i,i) 下一个 无构造函数: Dim pt As Point For i As
第一个较短,特别是若构造函数有更多参数,但在循环中使用它明智吗(比如说游戏循环每秒触发60次)?或者这两个编译为相同的机器代码?我希望它们给出相同的机器代码,假设
Point
是.NET结构(一种值类型,而不是引用类型),并且假设Point
构造函数只对X
和Y
字段赋值。我希望JIT内联调用点
构造函数
但是,IL中有一个区别,因为编译器没有内联构造函数。正如您所期望的,第一段代码对构造函数进行1000次调用,而第二段代码对字段存储操作进行1000对调用
和往常一样,“哪一个更快?”问题,写下它们并计时。对于这一点很有用。我希望它们给出相同的机器代码,假设
点
是.NET结构(一种值类型,与引用类型相反),并且假设点
构造函数只为X
和Y
字段赋值。我希望JIT内联调用点
构造函数
但是,IL中有一个区别,因为编译器没有内联构造函数。正如您所期望的,第一段代码对构造函数进行1000次调用,而第二段代码对字段存储操作进行1000对调用
和往常一样,“哪一个更快?”问题,写下它们并计时。对这一点很有用。这段代码的计时实际上是不可能的。只有运行代码的发布版本,您才能获得实际的计时结果。这也会影响JIT优化器。它足够聪明,可以看到“pt”实际上并没有在任何地方使用,它删除了所有分配它的代码。你会在同一个时间结束,仍然什么都不知道 要强制JIT优化器实际发出分配代码,您必须使用“pt”进行一些操作。比如: 但现在您将计时Console.WriteLine()所需的时间,而不是了解有关赋值效率的任何信息。然而,在这种情况下值得一看的是生成的机器代码。以下是我的x86 JIT编译器在启用优化器的发布版本中生成的注释版本:
00000008 xor eax,eax ; New Point
0000000a mov dword ptr [ebp-10h],eax ; pt.X = 0
0000000d mov dword ptr [ebp-0Ch],eax ; pt.Y = 0
[first fragment]
00000010 mov esi,1 ; i = 1
pt = New Point(i, i)
00000015 mov dword ptr [ebp-10h],esi ; pt.X = i
00000018 mov dword ptr [ebp-0Ch],esi ; pt.Y = i
[elided]
00000036 add esi,1 ; i = i + 1
00000039 jo 0000007D ; overflow check
0000003b cmp esi,3E8h ; i <= 1000?
00000041 jle 00000015 ; Yes: loop
[2nd fragment]
00000043 mov esi,1 ; i = 1
pt.X = i
00000048 mov dword ptr [ebp-10h],esi ; pt.X = i
pt.Y = i
0000004b mov dword ptr [ebp-0Ch],esi ; pt.Y = i
[elided]
00000069 add esi,1 ; i = i + 1
0000006c jo 0000007D ; overflow check
0000006e cmp esi,3E8h ; i <= 1000?
00000074 jle 00000048 : Yes: loop
00000008异或eax,eax;新点
0000000 A mov dword ptr[ebp-10h],eax;pt.X=0
0000000 d mov dword ptr[ebp-0Ch],eax;第Y部分=0
[第一段]
00000010部电影,1部;i=1
pt=新点(i,i)
000000 15 mov德沃德ptr[ebp-10h],esi;pt.X=i
000000 18 mov德沃德ptr[ebp-0Ch],esi;pt.Y=i
[省略]
00000036增加esi,1;i=i+1
00000039jo0000007d;溢出检查
0000003b cmp esi,3E8h;我这段代码的计时实际上是不可能的。只有运行代码的发布版本,您才能获得实际的计时结果。这也会影响JIT优化器。它足够聪明,可以看到“pt”实际上并没有在任何地方使用,它删除了所有分配它的代码。你会在同一个时间结束,仍然什么都不知道
要强制JIT优化器实际发出分配代码,您必须使用“pt”进行一些操作。比如:
但现在您将计时Console.WriteLine()所需的时间,而不是了解有关赋值效率的任何信息。然而,在这种情况下值得一看的是生成的机器代码。以下是我的x86 JIT编译器在启用优化器的发布版本中生成的注释版本:
00000008 xor eax,eax ; New Point
0000000a mov dword ptr [ebp-10h],eax ; pt.X = 0
0000000d mov dword ptr [ebp-0Ch],eax ; pt.Y = 0
[first fragment]
00000010 mov esi,1 ; i = 1
pt = New Point(i, i)
00000015 mov dword ptr [ebp-10h],esi ; pt.X = i
00000018 mov dword ptr [ebp-0Ch],esi ; pt.Y = i
[elided]
00000036 add esi,1 ; i = i + 1
00000039 jo 0000007D ; overflow check
0000003b cmp esi,3E8h ; i <= 1000?
00000041 jle 00000015 ; Yes: loop
[2nd fragment]
00000043 mov esi,1 ; i = 1
pt.X = i
00000048 mov dword ptr [ebp-10h],esi ; pt.X = i
pt.Y = i
0000004b mov dword ptr [ebp-0Ch],esi ; pt.Y = i
[elided]
00000069 add esi,1 ; i = i + 1
0000006c jo 0000007D ; overflow check
0000006e cmp esi,3E8h ; i <= 1000?
00000074 jle 00000048 : Yes: loop
00000008异或eax,eax;新点
0000000 A mov dword ptr[ebp-10h],eax;pt.X=0
0000000 d mov dword ptr[ebp-0Ch],eax;第Y部分=0
[第一段]
00000010部电影,1部;i=1
pt=新点(i,i)
000000 15 mov德沃德ptr[ebp-10h],esi;pt.X=i
000000 18 mov德沃德ptr[ebp-0Ch],esi;pt.Y=i
[省略]
00000036增加esi,1;i=i+1
00000039jo0000007d;溢出检查
0000003b cmp esi,3E8h;谢谢。我希望得到这样的答案。我喜欢编写清晰的代码,但是老的“这是最优的”一直在我脑海中闪现。谢谢。我希望得到这样的答案。我喜欢编写清晰的代码,但旧的“这是最优的”一直在我脑海中闪现。