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

时间:2021-12-06 02:58:26

I'm doing a bit of coding, where I have to write this sort of code:

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

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

I wonder if it should be re-written as

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

array[i]=true;

This raises the question: are comparisions faster than assignments?

这提出了一个问题:比分配更快的比较?

What about differences from language to language? (contrast between java & cpp, eg.)

从语言到语言的差异怎么样? (例如java和cpp之间的对比)

NOTE: I've heard that "premature optimization is the root of all evil." I don't think that applies here :)

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

12 个解决方案

#1


Well, since you say you're sure that this matters you should just write a test program and measure to find the difference.

好吧,因为你说你确定这很重要,你应该写一个测试程序和测量来找到差异。

Comparison can be faster if this code is executed on multiple variables allocated at scattered addresses in memory. With comparison you will only read data from memory to the processor cache, and if you don't change the variable value when the cache decides to to flush the line it will see that the line was not changed and there's no need to write it back to the memory. This can speed up execution.

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

#2


This isn't just premature optimization, this is micro-optimization, which is an irrelevant distraction.

这不仅仅是过早优化,这是微观优化,这是一种无关紧要的分心。

Assuming your array is of boolean type then your comparison is unnecessary, which is the only relevant observation.

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

#3


Edit: I wrote a script in PHP. I just noticed that there was a glaring error in it meaning the best-case runtime was being calculated incorrectly (scary that nobody else noticed!)

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

Best case just beats outright assignment but worst case is a lot worse than plain assignment. Assignment is likely fastest in terms of real-world data.

最好的情况只是击败彻底的任务,但最坏的情况比简单的任务更糟糕。就实际数据而言,分配可能是最快的。

Output:

  • assignment in 0.0119960308075 seconds
  • 分配在0.0119960308075秒

  • worst case comparison in 0.0188510417938 seconds
  • 最差情况比较0.0188510417938秒

  • best case comparison in 0.0116770267487 seconds
  • 0.0116770267487秒内的最佳案例比较

Code:

<?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;
}

#4


I believe if comparison and assignment statements are both atomic(ie one processor instruction) and the loop executes n times, then in the worst-case comparing then assigning would require n+1(comparing on every iteration plus setting the assignement) executions whereas constantly asssigning the bool would require n executions. Therefore the second one is more efficient.

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

#5


Depends on the language. However looping through arrays can be costly as well. If the array is in consecutive memory, the fastest is to write 1 bits (255s) across the entire array with memcpy assuming your language/compiler can do this.

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

Thus performing 0 reads-1 write total, no reading/writing the loop variable/array variable (2 reads/2 writes each loop) several hundred times.

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

#6


I really wouldn't expect there to be any kind of noticeable performance difference for something as trivial as this so surely it comes down to what gives you clear, more readable code. I my opinion that would be always assigning true.

我真的不希望有任何明显的性能差异对于像这样微不足道的东西,所以肯定它归结为什么给你清晰,更可读的代码。我的意见总是指定真实的。

#7


Might give this a try:

可能试一试:

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

But really the only way to know for sure is to profile, I'm sure pretty much any compiler would see the comparison to false as unnecessary and optimize it out.

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

#8


It all depends on the data type. Assigning booleans is faster than first comparing them. But that may not be true for larger value-based datatypes.

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

#9


As others have noted, this is micro-optimization.

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

(In politics or journalism, this is known as navel-gazing ;-)

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

Is the program large enough to have more than a couple layers of function/method/subroutine calls?

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

If so, it probably had some avoidable calls, and those can waste hundreds as much time as low-level inefficiencies.

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

On the assumption that you have removed those (which few people do), then by all means run it 10^9 times under a stopwatch, and see which is faster.

假设你已经删除了那些(很少人这样做),那么一定要在秒表下运行10 ^ 9次,看看哪个更快。

#10


Why would you even write the first version? What's the benefit of checking to see if something is false before setting it true. If you always are going to set it true, then always set it true.

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

When you have a performance bottleneck that you've traced back to setting a single boolean value unnecessarily, come back and talk to us.

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

#11


I remember in one book about assembly language the author claimed that if condition should be avoided, if possible. It is much slower if the condition is false and execution has to jump to another line, considerably slowing down performance. Also since programs are executed in machine code, I think 'if' is slower in every (compiled) language, unless its condition is true almost all the time.

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

#12


If you just want to flip the values, then do:

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

array[i] = !array[i];

Performance using this is actually worse though, as instead of only having to do a single check for a true false value then setting, it checks twice.

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

If you declare a 1000000 element array of true,false, true,false pattern comparision is slower. (var b = !b) essentially does a check twice instead of once

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

#1


Well, since you say you're sure that this matters you should just write a test program and measure to find the difference.

好吧,因为你说你确定这很重要,你应该写一个测试程序和测量来找到差异。

Comparison can be faster if this code is executed on multiple variables allocated at scattered addresses in memory. With comparison you will only read data from memory to the processor cache, and if you don't change the variable value when the cache decides to to flush the line it will see that the line was not changed and there's no need to write it back to the memory. This can speed up execution.

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

#2


This isn't just premature optimization, this is micro-optimization, which is an irrelevant distraction.

这不仅仅是过早优化,这是微观优化,这是一种无关紧要的分心。

Assuming your array is of boolean type then your comparison is unnecessary, which is the only relevant observation.

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

#3


Edit: I wrote a script in PHP. I just noticed that there was a glaring error in it meaning the best-case runtime was being calculated incorrectly (scary that nobody else noticed!)

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

Best case just beats outright assignment but worst case is a lot worse than plain assignment. Assignment is likely fastest in terms of real-world data.

最好的情况只是击败彻底的任务,但最坏的情况比简单的任务更糟糕。就实际数据而言,分配可能是最快的。

Output:

  • assignment in 0.0119960308075 seconds
  • 分配在0.0119960308075秒

  • worst case comparison in 0.0188510417938 seconds
  • 最差情况比较0.0188510417938秒

  • best case comparison in 0.0116770267487 seconds
  • 0.0116770267487秒内的最佳案例比较

Code:

<?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;
}

#4


I believe if comparison and assignment statements are both atomic(ie one processor instruction) and the loop executes n times, then in the worst-case comparing then assigning would require n+1(comparing on every iteration plus setting the assignement) executions whereas constantly asssigning the bool would require n executions. Therefore the second one is more efficient.

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

#5


Depends on the language. However looping through arrays can be costly as well. If the array is in consecutive memory, the fastest is to write 1 bits (255s) across the entire array with memcpy assuming your language/compiler can do this.

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

Thus performing 0 reads-1 write total, no reading/writing the loop variable/array variable (2 reads/2 writes each loop) several hundred times.

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

#6


I really wouldn't expect there to be any kind of noticeable performance difference for something as trivial as this so surely it comes down to what gives you clear, more readable code. I my opinion that would be always assigning true.

我真的不希望有任何明显的性能差异对于像这样微不足道的东西,所以肯定它归结为什么给你清晰,更可读的代码。我的意见总是指定真实的。

#7


Might give this a try:

可能试一试:

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

But really the only way to know for sure is to profile, I'm sure pretty much any compiler would see the comparison to false as unnecessary and optimize it out.

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

#8


It all depends on the data type. Assigning booleans is faster than first comparing them. But that may not be true for larger value-based datatypes.

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

#9


As others have noted, this is micro-optimization.

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

(In politics or journalism, this is known as navel-gazing ;-)

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

Is the program large enough to have more than a couple layers of function/method/subroutine calls?

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

If so, it probably had some avoidable calls, and those can waste hundreds as much time as low-level inefficiencies.

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

On the assumption that you have removed those (which few people do), then by all means run it 10^9 times under a stopwatch, and see which is faster.

假设你已经删除了那些(很少人这样做),那么一定要在秒表下运行10 ^ 9次,看看哪个更快。

#10


Why would you even write the first version? What's the benefit of checking to see if something is false before setting it true. If you always are going to set it true, then always set it true.

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

When you have a performance bottleneck that you've traced back to setting a single boolean value unnecessarily, come back and talk to us.

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

#11


I remember in one book about assembly language the author claimed that if condition should be avoided, if possible. It is much slower if the condition is false and execution has to jump to another line, considerably slowing down performance. Also since programs are executed in machine code, I think 'if' is slower in every (compiled) language, unless its condition is true almost all the time.

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

#12


If you just want to flip the values, then do:

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

array[i] = !array[i];

Performance using this is actually worse though, as instead of only having to do a single check for a true false value then setting, it checks twice.

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

If you declare a 1000000 element array of true,false, true,false pattern comparision is slower. (var b = !b) essentially does a check twice instead of once

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