gpt4 book ai didi

c# - 为什么条件(三元)运算符看起来明显更快?

转载 作者:太空狗 更新时间:2023-10-29 22:53:02 30 4
gpt4 key购买 nike

编辑

如果我正确使用 Stopwatch 并将迭代次数提高两个数量级,我会得到

Ternary took 22404ms

Normal took 21403ms

这些结果更接近我的预期,让我觉得这个世界一切都很好(如果不是我的代码。)

三元/条件运算符实际上稍微慢一些。


this question 开始,我有一部分answered .

我在 x64 Release模式下编译这个控制台应用程序,启用优化,并在没有附加调试器的情况下从命令行运行它。

using System; 
using System.Diagnostics;

class Program
{
static void Main()
{
var stopwatch = new Stopwatch();

var ternary = Looper(10, Ternary);
var normal = Looper(10, Normal);

if (ternary != normal) {
throw new Exception();
}

stopwatch.Start();
ternary = Looper(10000000, Ternary);
stopWatch.Stop();
Console.WriteLine(
"Ternary took {0}ms",
stopwatch.ElapsedMilliseconds);

stopwatch.Start();
normal = Looper(10000000, Normal);
stopWatch.Stop();
Console.WriteLine(
"Normal took {0}ms",
stopwatch.ElapsedMilliseconds);

if (ternary != normal) {
throw new Exception();
}

Console.ReadKey();
}

static int Looper(int iterations, Func<bool, int, int> operation)
{
var result = 0;
for (int i = 0; i < iterations; i++)
{
var condition = result % 11 == 4;
var value = ((i * 11) / 3) % 5;
result = operation(condition, value);
}

return result;
}

static int Ternary(bool condition, in value)
{
return value + (condition ? 2 : 1);
}

static int Normal(int iterations)
{
if (condition)
{
return = 2 + value;
}

return = 1 + value;
}
}

我没有得到任何异常,控制台的输出很接近,

Ternary took 107ms

Normal took 230ms

当我为两个逻辑函数分解 CIL 时,我得到了这个,

... Ternary ...
{
: ldarg.1 // push second arg
: ldarg.0 // push first arg
: brtrue.s T // if first arg is true jump to T
: ldc.i4.1 // push int32(1)
: br.s F // jump to F
T: ldc.i4.2 // push int32(2)
F: add // add either 1 or 2 to second arg
: ret // return result
}

... Normal ...
{
: ldarg.0 // push first arg
: brfalse.s F // if first arg is false jump to F
: ldc.i4.2 // push int32(2)
: ldarg.1 // push second arg
: add // add second arg to 2
: ret // return result
F: ldc.i4.1 // push int32(1)
: ldarg.1 // push second arg
: add // add second arg to 1
: ret // return result
}

虽然 Ternary CIL 稍微短一些,但在我看来,这两个函数通过 CIL 的执行路径需要 3 次加载、1 次或 2 次跳转和一次返回。为什么 Ternary 函数看起来快两倍。

我知道,在实践中,它们都非常快,而且确实足够快,但是,我想了解其中的差异。

最佳答案

两者花费的时间几乎完全相同。

你的结果是错误的,因为你没有正确使用 Stopwatch。 “正常”的测量值包括两个 looper 所花费的时间。

如果你改变第二个

stopwatch.Start();

stopwatch.Restart();

然后你会得到正确的结果。


顺便说一下,为了获得更公平的比较,您可能应该执行

    return (condition ? value + 2 : value + 1);

代替

    return value + (condition ? 2 : 1);

这样它就完全等同于另一个函数。否则,您不仅在衡量条件运算符。

关于c# - 为什么条件(三元)运算符看起来明显更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12462418/

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