gpt4 book ai didi

c# - 什么 VS 调试器使增量运算符执行得比什么都不做更快?

转载 作者:太空狗 更新时间:2023-10-29 21:40:32 24 4
gpt4 key购买 nike

这是不言自明的代码(执行十亿次操作):

int k = 0;

Stopwatch sw = new Stopwatch();
sw.Start();
for (int a = 0; a < 1000; a++)
for (int b = 0; b < 1000; b++)
for (int c = 0; c < 1000; c++)
k++;

sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);

sw = new Stopwatch();
sw.Start();

for (int a = 0; a < 1000; a++)
for (int b = 0; b < 1000; b++)
for (int c = 0; c < 1000; c++)
; // NO-OP

sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);

结果(至少在我的电脑上)大约(以毫秒为单位)

2168
2564

第二个总是长半秒左右。

增加一个变量 10 亿次怎么可能比执行相同次数的空操作运行时间更长?

编辑:这只发生在 DEBUG 上。 Release 正确地做到了这一点,第一个持续时间更长,至少在我的电脑上是这样。正如评论中指出的那样,即使在 RELEASE 版本中,也有人遇到过这个问题。但是在 DEBUG 上发生了什么会产生这种效果?

最佳答案

问题如 Azodious 所述,您不能使用 Debug模式来测量时间,因为它不会准确。

开启 Release模式后,我得到以下数字:

递增 k:445

NOP:402

递增版本中还有 4 条 IL 指令:

IL_0001:  ldc.i4.0    
IL_0002: stloc.0
IL_0003: ldc.i4.0
IL_0004: stloc.1
IL_0005: br.s IL_003B
IL_0007: ldc.i4.0
IL_0008: stloc.2
IL_0009: br.s IL_0029
IL_000B: ldc.i4.0
IL_000C: stloc.3
IL_000D: br.s IL_0017
IL_000F: ldloc.0
IL_0010: ldc.i4.1
IL_0011: add
IL_0012: stloc.0
IL_0013: ldloc.3
IL_0014: ldc.i4.1
IL_0015: add
IL_0016: stloc.3
IL_0017: ldloc.3
IL_0018: ldc.i4 E8 03 00 00
IL_001D: clt
IL_001F: stloc.s 04
IL_0021: ldloc.s 04
IL_0023: brtrue.s IL_000F
IL_0025: ldloc.2
IL_0026: ldc.i4.1
IL_0027: add
IL_0028: stloc.2
IL_0029: ldloc.2
IL_002A: ldc.i4 E8 03 00 00
IL_002F: clt
IL_0031: stloc.s 04
IL_0033: ldloc.s 04
IL_0035: brtrue.s IL_000B
IL_0037: ldloc.1
IL_0038: ldc.i4.1
IL_0039: add
IL_003A: stloc.1
IL_003B: ldloc.1
IL_003C: ldc.i4 E8 03 00 00
IL_0041: clt
IL_0043: stloc.s 04
IL_0045: ldloc.s 04
IL_0047: brtrue.s IL_0007

NOP-verison 有相同数量的分支但少了一个add:

IL_0001:  ldc.i4.0    
IL_0002: stloc.0
IL_0003: ldc.i4.0
IL_0004: stloc.1
IL_0005: br.s IL_0037
IL_0007: ldc.i4.0
IL_0008: stloc.2
IL_0009: br.s IL_0025
IL_000B: ldc.i4.0
IL_000C: stloc.3
IL_000D: br.s IL_0013
IL_000F: ldloc.3
IL_0010: ldc.i4.1
IL_0011: add
IL_0012: stloc.3
IL_0013: ldloc.3
IL_0014: ldc.i4 E8 03 00 00
IL_0019: clt
IL_001B: stloc.s 04
IL_001D: ldloc.s 04
IL_001F: brtrue.s IL_000F
IL_0021: ldloc.2
IL_0022: ldc.i4.1
IL_0023: add
IL_0024: stloc.2
IL_0025: ldloc.2
IL_0026: ldc.i4 E8 03 00 00
IL_002B: clt
IL_002D: stloc.s 04
IL_002F: ldloc.s 04
IL_0031: brtrue.s IL_000B
IL_0033: ldloc.1
IL_0034: ldc.i4.1
IL_0035: add
IL_0036: stloc.1
IL_0037: ldloc.1
IL_0038: ldc.i4 E8 03 00 00
IL_003D: clt
IL_003F: stloc.s 04
IL_0041: ldloc.s 04
IL_0043: brtrue.s IL_0007

这些是在没有优化的情况下编译的,因为我想看看到底发生了什么。

它们在现实中的唯一区别是:

IL_0012:  stloc.0     
IL_0013: ldloc.3
IL_0014: ldc.i4.1
IL_0015: add

简单地说:您得到的数字很奇怪,因为您处于 Debug模式。

关于c# - 什么 VS 调试器使增量运算符执行得比什么都不做更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12471840/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com