以下两种情况有性能差异吗?

发布于 11-17 14:24 字数 453 浏览 4 评论 0原文

以下两种情况之间是否存在性能差异:
第一:

int test_some_condition(void);

if( some_variable == 2 && test_some_condition())
{
    //body
}

第二:

int test_some_condition(void);

if( some_variable == 2 )
{
    if(test_some_condition())
    {
        //body
    }
}

更新:我知道如何创建测试并测量每个案例的性能或查看为每个案例生成的组件,但我确信我是这不是第一个遇到这个问题的人,如果已经测试过这个问题的人能给我一个简单的是/否的答案,那就太好了。

is there any performance difference between the following two cases:
First:

int test_some_condition(void);

if( some_variable == 2 && test_some_condition())
{
    //body
}

Second:

int test_some_condition(void);

if( some_variable == 2 )
{
    if(test_some_condition())
    {
        //body
    }
}

UPDATE: I know how to create a test and measure the performance of each case or to look at the assembly produced for each case but I am sure I am not the first one to come across this question and it would be great if someone who has already tested that can be me a simple yes/no answer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

一抹淡然2024-11-24 14:24:08

有什么区别?

可读性?是的,有区别。第一个更清晰,更好地表达了您的意图。而且它在编辑器中占用的行数也更少,这本身不一定是一个优势,但它确实使代码更易于阅读,并且对于后面想要编辑代码的任何人来说一目了然。

性能/“速度”?不。我愿意用实际金钱打赌,一旦您通过打开优化的编译器运行这两个代码片段,绝对不会有明显的差异。即使优化被禁用,也不需要太多就能说服我在同样的情况下下注。

为什么?因为在 C(以及我所知道的所有 C 派生语言)中,&& 运算符执行短路评估,这意味着如果第一个如果条件的计算结果为 false,那么它甚至不必计算第二个条件,因为整个语句不可能都为 true。

在 VB 6 的糟糕岁月中,当 And 运算符不执行短路计算时,嵌套 if 语句是一种常见的“优化”技巧。我无法想象在 C 代码中使用它的目的,除非它增强了可读性。老实说,如果您运行的编译器使这两个代码片段在性能方面完全等效,那么是时候扔掉该编译器并停止使用它了。这是最基本的优化,对于编译器编写者来说是“唾手可得的果实”。如果他们不能解决这个问题,我就不会信任他们处理你的其余代码。

但是,总的来说,担心这类事情(这绝对属于“微优化”的范畴)并不能帮助您编写更好的代码或成为更好的程序员。这只会让你浪费大量时间在 Stack Overflow 上提问,并为像我这样每周针对 2-3 个类似问题发布相同答案的用户的声誉做出贡献。那时您不用花时间编写代码并以切实的方式提高您的技能。

Difference in terms of what?

Readability? Yes, there's a difference. The first is much clearer and much better expresses your intent. And it also takes up fewer lines in the editor, which is not necessarily an advantage in itself, but it does make the code easier to read and grok at a glance for anyone who comes behind and wants to edit it.

Performance/"speed"? No. I'd be willing to bet actual money that there is absolutely no discernible difference once you run those two snippets of code through a compiler with optimizations turned on. And it wouldn't take much to convince me to bet on that same case even with optimizations disabled.

Why? Because in C (and all of the C-derived languages that I know of), the && operator performs short-circuit evaluation, which means that if the first condition evaluates to false, then it doesn't even bother to evaluate the second condition, because there's no way that the entire statement could ever turn out to be true.

Nesting the if statements was a common "optimization" trick in the bad old days of VB 6 when the And operator did not perform short-circuit evaluation. There's no purpose that I can imagine to using it in C code, unless it enhances readability. And honestly, if you run across a compiler that doesn't render these two code snippets completely equivalent in terms of performance, then it's time to throw that compiler away and stop using it. This is the most basic optimization under the sun, a "low-hanging fruit" for compiler writers. If they can't get this right, I wouldn't trust them with the rest of your code.

But, in general, worrying about this sort of thing (which definitely falls under the category of a "micro-optimization") is not helping you to write better code or become a better programmer. It's just causing you to waste a lot of time asking questions on Stack Overflow and contributing to the reputation of users like me who post this same answer to 2–3 similar questions a week. And that's time you're not spending writing code and improving your skills in tangible ways.

孤单情人2024-11-24 14:24:08

任何人都可以真正了解现代编译器的唯一方法是查看机器代码。

The only way anyone can really tell with a modern compiler is to look at the machine code.

挽袖吟2024-11-24 14:24:08

应该没有区别。 如果存在差异,则可能无法测量(即使您执行数百万次,也不会得到结论性的结果)。

There should be no difference. If there is a difference, it's likely not measurable (even if you do it millions of times you won't get conclusive results).

说不完的你爱2024-11-24 14:24:08

在运行 10.000.000 次的循环中测试这两个示例会得出:

$ time ./test1

real    0m0.045s
user    0m0.044s
sys     0m0.001s

$ time ./test2

real    0m0.045s
user    0m0.043s
sys     0m0.003s

另外,请记住,如果表达式的第一部分失败,则永远不会计算第二个表达式。在第一个示例中这可能不太清楚。

此外,在第一个计算表达式返回 false 的情况下:

$ time ./test1_1

real    0m0.035s
user    0m0.034s
sys     0m0.001s
$ time ./test2_1

real    0m0.035s
user    0m0.034s
sys     0m0.000s

Testing these two examples in a loop running 10.000.000 times gives:

$ time ./test1

real    0m0.045s
user    0m0.044s
sys     0m0.001s

$ time ./test2

real    0m0.045s
user    0m0.043s
sys     0m0.003s

Also, keep in mind that if the first part of the expression fails, the second expression will never be evaluated. This is maybe not so clear in the first example.

Also, in conditions where the first evaluated expression returns false:

$ time ./test1_1

real    0m0.035s
user    0m0.034s
sys     0m0.001s
$ time ./test2_1

real    0m0.035s
user    0m0.034s
sys     0m0.000s
只等公子2024-11-24 14:24:08

如果您正在考虑第一个版本是否始终调用 test_some_condition 但第二个版本仅在第一个条件为真时才调用它,那么答案是两个版本是等效的,因为 AND 运算符是惰性的并且

该标准保证了这种行为。这使得这样的说法是合法的:

if (array_size > n && my_array[n] == 1) { ... }

如果没有惰性保证,这将是损坏的代码。

If you are thinking whether the first version always calls test_some_condition but the second version calls it only if the first condition is true, then the answer is that both versions are equivalent because the AND operator is lazy and will not evaluate its second argument if the first is already false.

The standard guarantees this behaviour. This makes it legal to say:

if (array_size > n && my_array[n] == 1) { ... }

This would be broken code without the laziness guarantee.

小…楫夜泊2024-11-24 14:24:08

这两个示例在逻辑上是等效的,前提是复合条件是延迟计算的,这意味着在 a && 中b,当已知 a 为 false 时,将不会计算 b。因此,即使存在差异,我也不会关心,因为这可能是您正在使用的编译器的人工制品(或错误),并且它可能会随着下一个版本或错误修复而改变。

The two samples are logically equivalent, provided that compound conditions are lazily evaluated, meaning that in a && b, b won't be evaluated when a is known to be false. So even if there were a difference I wouldn't care because that might be an artefact (or a bug) of the compiler you're using, and it might change with the next release or bugfix.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文