我想将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)); }
答案 0 :(得分:5)
它可能不会影响程序的运行速度,但可以增加使程序正确的几率。这很有效率!
答案 1 :(得分:1)
不可能肯定地说。如果您想100%确定,请检查生成的程序集(或者只是执行代码的时间)。
但是,有两个可能对您有帮助的观察结果:
struct
与float
的尺寸相同,因此没有浪费的空间。并且没有不必要的间接:可以像以前一样有效地访问包含的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)
对于任何物有所值的编译器(即使它是免费的),使用普通浮点数都没有任何开销。