哪个更快?比较还是分配?

时间:2009-05-26 12:28:42

标签: performance optimization refactoring

我正在做一些编码,我必须编写这种代码:

if( array[i]==false )
    array[i]=true;

我想知道它是否应该重写为

array[i]=true;

这就提出了一个问题:比例分配的速度要快吗?

语言与语言的差异如何? (java和cpp之间的对比,例如。)

注意:我听说“过早优化是所有邪恶的根源。”我不认为这适用于:)

12 个答案:

答案 0 :(得分:26)

这不仅仅是premature optimization,而是 micro-optimization ,这是一种无关紧要的分心。

假设您的数组是布尔类型,那么您的比较是不必要的,这是唯一相关的观察。

答案 1 :(得分:18)

好吧,既然你说你确定这很重要,那么你应该写一个测试程序并测量一下,找出差异。

如果在内存中分散地址分配的多个变量上执行此代码,则比较速度会更快。通过比较,您只会将内存中的数据读取到处理器缓存中,如果在缓存决定刷新行时不更改变量值,则会看到该行未更改且无需将其写回记忆。这可以加快执行速度。

答案 2 :(得分:14)

编辑:我用PHP编写了一个脚本。我只是注意到它有一个明显的错误,这意味着最好的情况运行时计算不正确(可怕没人注意到!)

最佳案例只是击败直接分配,但最糟糕的情况是很糟糕而不是简单的任务。就实际数据而言,分配可能是最快的。

输出:

  • 分配0.0119960308075秒
  • 最差情况比较0.0188510417938秒
  • 0.0116770267487秒内的最佳案例比较

代码:

<?php
$arr = array();

$mtime = explode(" ", microtime());
$starttime = $mtime[1] + $mtime[0];

reset_arr($arr);

for ($i=0;$i<10000;$i++)
    $arr[i] = true;


$mtime = explode(" ", microtime());
$firsttime = $mtime[1] + $mtime[0];
$totaltime = ($firsttime - $starttime);
echo "assignment in ".$totaltime." seconds<br />"; 

reset_arr($arr);

for ($i=0;$i<10000;$i++)
    if ($arr[i])
        $arr[i] = true;

$mtime = explode(" ", microtime());
$secondtime = $mtime[1] + $mtime[0];
$totaltime = ($secondtime - $firsttime);
echo "worst case comparison in ".$totaltime." seconds<br />"; 

reset_arr($arr);

for ($i=0;$i<10000;$i++)
    if (!$arr[i])
        $arr[i] = false;

$mtime = explode(" ", microtime());
$thirdtime = $mtime[1] + $mtime[0];
$totaltime = ($thirdtime - $secondtime);
echo "best case comparison in ".$totaltime." seconds<br />"; 

function reset_arr($arr) {
    for ($i=0;$i<10000;$i++)
        $arr[$i] = false;
}

答案 3 :(得分:3)

我相信如果比较和赋值语句都是原子的(即一个处理器指令)并且循环执行n次,那么在最坏情况下比较然后分配将需要n + 1(比较每次迭代加上设置分配)执行虽然不断指定布尔将需要n次执行。因此第二个更有效率。

答案 4 :(得分:1)

取决于语言。然而,循环遍历数组也是昂贵的。如果数组在连续的内存中,最快的是使用memcpy在整个数组中写入1位(255s),假设您的语言/编译器可以执行此操作。

因此执行0次读取-1次写入总数,没有读取/写入循环变量/数组变量(2次读取/ 2次写入每个循环)数百次。

答案 5 :(得分:0)

我真的不希望在某些事情上有任何明显的性能差异,因为这肯定会归结为为您提供清晰,可读性更强的代码。我认为这总是真实的。

答案 6 :(得分:0)

可以尝试一下:

if(!array[i])
    array[i]=true;

但实际上唯一明确的方法就是分析,我确信任何编译器都会将这种比较视为不必要并将其优化出来。

答案 7 :(得分:0)

这一切都取决于数据类型。分配布尔值比首先比较布尔值要快。但对于较大的基于值的数据类型,情况可能并非如此。

答案 8 :(得分:0)

正如其他人所说,这是微观优化。

(在政治或新闻业,这被称为肚脐凝视; - )

程序是否足够大,可以进行多层函数/方法/子程序调用?

如果是这样的话,它可能会有一些可以避免的呼叫,这些可能会浪费数百个低效低效的时间。

假设您有removed those(很少有人这样做),那么一定要在秒表下运行10 ^ 9次,看看哪个更快。

答案 9 :(得分:0)

你为什么要写第一个版本?在将其设置为true之前检查某些内容是否为假有什么好处。如果你总是将它设置为true,那么总是将其设置为true。

当您遇到性能瓶颈时,您已经追溯到不必要地设置一个布尔值,请回来与我们交谈。

答案 10 :(得分:0)

我记得在一本关于汇编语言的书中,作者声称如果可能的话应该避免条件。 如果条件为false并且执行必须跳转到另一行,则速度要慢得多,这会大大降低性能。此外,由于程序是在机器代码中执行的,我认为“if”在每种(编译)语言中都比较慢,除非它的条件几乎一直都是真的。

答案 11 :(得分:-1)

如果您只想翻转值,请执行以下操作:

array[i] = !array[i];

使用它的性能实际上更糟糕,因为它不是只需要检查真假值然后设置,而是检查两次。

如果声明一个1000000元素数组的true,false,true,false,模式比较会更慢。 (var b =!b)基本上检查两次而不是一次