#用C定义效率

#用C定义效率,c,performance,C,Performance,我是C新手,想知道哪种编程方式更有效或更可取: 备选方案A: #define flag true void Foo() { for (size_t i = 0; i < veryBigNumber; i++) { if (flag) doSomething1(); doSomething2(); } } #定义标志true void Foo() { 对于(大小i=0;i

我是C新手,想知道哪种编程方式更有效或更可取:

备选方案A:

#define flag true

void Foo()
{
   for (size_t i = 0; i < veryBigNumber; i++)
   {
      if (flag)
         doSomething1();
      doSomething2();
   }
}
#定义标志true
void Foo()
{
对于(大小i=0;i
备选案文B:

#define flag

void Foo()
{
   for (size_t i = 0; i < veryBigNumber; i++)
   {
#if defined(flag)
         doSomething1();
#endif
      doSomething2();
   }
}
#定义标志
void Foo()
{
对于(大小i=0;i
视情况而定。下面的代码在编译时进行了完整的分析,因此
doSomething
在运行时将始终在没有任何不必要的开销的情况下执行。较高版本在编译时扩展为
if
语句;
if
条件可能会在运行时进行评估。但是,如果激活了代码优化,编译器可能会决定
if
条件永远不能为false,因此整个
if
语句可能会被删除。

如果未定义
标志
,则第二个语句会导致生成的代码减少

重要的是,省略的代码是
if
语句,因此运行时效率也会更好,因为
if
语句没有不必要地执行
veryBigNumber


编译器可能能够通过分析代码来优化
if
语句,但明确地“ifdefing”出代码将确保它是正确的。

除非您使用的是非常古老/愚蠢的编译器,否则它们应该是等价的。
#if
保证在编译时进行计算,但是任何现代编译器也会在编译时使用整数常量计算常规的
if


(无论如何,你离自己找到答案只有一步之遥。 只需在
veryBigNumber
中输入一个很大的数字,并对两个变量中的每一个进行计时。如果非常大的数字真的很大(数百万、数十亿),那么即使在外部对其进行计时(
time./a.out
从命令行),也会给您提供相当可靠的计时。)

建议:

您应该使用#ifdef代替#if defined(flag)。(良好编码实践)

代码应该是这样的:

定义:

 #define FLAG
使用:

#define是一个预编译器指令。因此,无论您编写什么,都将进行分析并插入代码

例如,在第一个示例中,条件将始终为真。编译器可能只会优化这个if()条件

同样,在第二个示例中,这是一个“编译器时”测试(#if),而不是运行时测试(if)

使用宏可以提高性能,因为它们有助于以类似于函数调用的方式组织代码,但宏代码是由编译器“内联”的。这减少了在运行时使用函数调用时需要跳转到内存中某个位置的开销


它们还有助于使处理保持不变的代码变得更容易。这使您的代码更容易阅读,编写起来也不那么痛苦(想象一下,每次必须使用它时都必须记住并插入一个常量值)。

您是否使用优化编译器进行了尝试?5块钱说两者速度相同。哦,为什么速度如此之快,即使二进制文件看起来也一样:)即使没有性能差异,源代码在语义上也是不同的。由于源代码与性能一样重要,您应该选择一个更准确地表达您意图的源代码。@legends2k,我是在Cuda中编译的,因为我是C/Cuda新手,我不确定它是如何/是否优化C代码的。
\define
指令本身如何影响代码执行速度?在编译时对它们进行评估。预处理器
#如果
条件应尽可能避免。如果把<代码>定义为< /代码>到其他文件,并且忘记包含该文件,会发生什么情况?条件将无声地失败。用自然条件或马可包装纸代替。你最后一段是什么意思?什么是常数码?“插入常量值”是什么意思?在第一个示例中,定义标志true。这意味着在编译之前,编译器将遍历您的代码,并在您使用标志的地方使用true替换。想象一下,如果您的行是#define flag 12143,并且需要在多个位置使用该值。要记住它并把它写下来,这将是一件很痛苦的事——只需写下它就更容易了。此外,如果没有宏,当您返回代码时,您必须尝试并记住值所表示的内容。阅读我链接的文章,看看如何将#define也用于更具表现力的代码。顺便说一句,Nathanial,在宏中使用大写字母是惯例(也是有充分理由的),那么其他人就会知道它是什么,以及在哪里可以找到它的定义。所以“旗帜”变成了“旗帜”。谢谢,我会这么做的。
#ifdef FLAG
     doSomething1();
#else
    doSomething2();
#endif