原生类型的封装是否会影响效率?

时间:2012-07-29 09:10:05

标签: c++ performance inline encapsulation abstraction

我想将float封装在两个结构中,例如:

struct AngleDeg {
    explicit AngleDeg(float angle):value(angle) {}
    float value;
};

struct AngleRad {
    explicit AngleRad(float angle):value(angle) {}
    float value;
};

然后在类中使用这些结构重载一个函数,如:

...
void DoStuff(AngleRad angle);
inline void DoStuff(AngleDeg angle) { DoStuff(Deg2Rad(angle.value)); }
...

这是否与使用以下两个函数一样有效?

void DoStuffRad(float angle);
inline void DoStuffDeg(float angle) { DoStuffRad(Deg2Rad(angle)); }

5 个答案:

答案 0 :(得分:5)

它可能不会影响程序的运行速度,但可以增加使程序正确的几率。这很有效率!

答案 1 :(得分:1)

不可能肯定地说。如果您想100%确定,请检查生成的程序集(或者只是执行代码的时间)。

但是,有两个可能对您有帮助的观察结果:

  • 首先,您的structfloat的尺寸相同,因此没有浪费的空间。并且没有不必要的间接:可以像以前一样有效地访问包含的float。所以没有根本原因,为什么它应该更慢
  • 但是,这可能会导致某些编译器优化失败。在某些情况下,它可能只为struct s生成与内置类型不同的代码。或者它可能使用floats的不同调用约定而不是“float的大小的对象”。

也许,也许不是。但速度差异不太可能产生可衡量的差异。

答案 2 :(得分:1)

我认为与@jalf一样的空间和访问但是不确定。所以我听了@quamrana和@jalf,做了一个运行时测试。

在调试模式下,结构的方法慢了大约30%,但在发布模式下它们是等效的。它可能依赖于编译器,但我将使用带有结构的方法。

答案 3 :(得分:1)

此问题已在Technical Report on C++ Performance中进行了调查。有关Stepanove抽象罚款基准的附录D.3。引用

  

基准测试的结构非常简单。它增加了2000年   数组翻倍25000次。它以13种不同的方式实现   介绍越来越多抽象的方法:
  0 - 使用简单   类似Fortran的循环。
  1 - 12使用STL样式累积模板   具有加功能对象的功能。
  1,3,5,7,9,11使用双打。   2,4,6,8,10,12使用双层双层包装。
  1,2 - 使用   常规指针。
  3,4,使用包裹在类中的指针   5,6-使用   包含在反向迭代器适配器中的指针   7,8 - 使用包裹   包含在反向迭代器适配器中的指针   9,10 - 使用指针   包装在反向迭代器中的反向迭代器适配器中   转接器。
  11,12 - 使用包装在反向迭代器中的包装指针   适配器包装在反向迭代器适配器中。

Ideone上的输出:现代编译器(gcc 4.5.1)的抽象惩罚(所有13个测试的几何平均值)小于1%。

答案 4 :(得分:0)

对于任何物有所值的编译器(即使它是免费的),使用普通浮点数都没有任何开销。