提高可读性而不会降低性能?

时间:2014-06-27 14:41:06

标签: c++ performance c++11 readability

我们假设我有三个函数f0, f1, f2,它们都有三个参数。我们还假设我有一个很大的函数bigFunc来调用,它将前三个函数的返回值作为参数。

我可能想打这样的电话:

bigFunc(f0(arg0, arg1, arg2), f1(arg3, arg4, arg5), f2(arg6, arg7, arg8));

这是一个很大的调用,所以我认为写这样的东西会更具可读性:

auto bigArg0 = f0(arg0, arg1, arg2);
auto bigArg1 = f1(arg3, arg4, arg5);
auto bigArg2 = f2(arg6, arg7, arg8);

bigFunc(bigArg0, bigArg1, bigArg2);

如果名称bigArg0, bigArg1, bigArg2允许我更具体地说明我正在做什么(例如,如果f0, f1, f2有点通用;那么你可以想到STL算法,那就特别棒了根据你给它的迭代器类型,它会做不同的事情。)

然而,问题在于,通过命名bigArg0, bigArg1, bigArg2,我不再使它们成为临时工,这(我认为)编译器难以优化。

所以,这是我的问题:如果我不想失去性能,那么正确的方法是什么? make bigArg0, bigArg1, bigArg2 const?将参数提供给bigFuncstd::move?两者兼而有之?

2 个答案:

答案 0 :(得分:3)

返回值的析构函数和复制构造函数是否具有可观察的行为,因为标准定义了它们?

如果他们不这样做并且编译器具有证明它的所有必要信息,编译器可以在不需要RVO异常的情况下隐藏副本。

如果你使用std::move,也许就是这种情况?无论哪种方式移动都可能比复制更好......

或许bigfunc通过常量引用获取其参数,在这种情况下,两种方式都会产生相同的代码......

答案 1 :(得分:1)

这是一个避免命名时间的解决方案:

bigFunc(
    f0(arg0, arg1, arg2),
    f1(arg3, arg4, arg5),
    f2(arg6, arg7, arg8)
);

放大的例子:

bigFunc(
    f0(
        f0_0(arg0, arg1, arg2),
        f0_1(arg3, arg4, arg5),
        f0_2(arg6, arg7, arg8)
    ),
    f1(
        f1_0(arg9, arg10, arg11),
        f1_1(arg12, arg13, arg14),
        f1_2(arg15, arg16, arg17)
    ),
    f2(
        f2_0(arg18, arg19, arg20),
        f2_1(arg21, arg22, arg23),
        f2_2(arg24, arg25, arg26)
    )
);

它在17条易于阅读的行中处理27个参数和13个函数调用。

在一个地方已经做了很多事情。到目前为止,它的扩展到它失去了可读性时,你应该开始将它的一部分放入单独的函数中和/或将参数组合成结构或类。