哪种转换更快,static_cast<int>()还是int()?

10

尝试看哪种转换更快(不一定更好):新的C++风格转换还是旧式的C风格转换。有什么想法吗?


1
你可以编写一个基准测试脚本。只需执行1000万次static_cast和1000万次int cast,然后查看哪个需要更长时间。我猜测它们将编译为相同的汇编指令。 - Kip
12
忽略它们几乎肯定在所有编译器上都可以编译通过,为什么这很重要?除非您已知性能问题,否则您应该编写清晰易懂的代码,避免难以阅读的微观优化,这些优化可能是无意义的。请使用static_cast<int>()。 - David Thornley
3
C风格强制类型转换是基于C++风格强制类型转换定义的(而且C风格强制类型转换可以转换为私有基类...)。因此它们实际上是相当等效的,两种方法在性能方面没有优劣之分。 - Johannes Schaub - litb
1
就此而言,int(10.4)不是C风格的转换,因为它不是有效的C语言(它调用了带有参数的函数int())。"C风格"的转换是(int)10.4 - Chris Lutz
2
@Chris:没错,但函数式转换与 C 风格转换完全等效 - Konrad Rudolph
7个回答

34

如果您将int()static_cast<int>()的等效功能进行比较,则两者没有任何区别。

在使用VC2008时:

    double d = 10.5;
013A13EE  fld         qword ptr [__real@4025000000000000 (13A5840h)] 
013A13F4  fstp        qword ptr [d] 
    int x = int(d);
013A13F7  fld         qword ptr [d] 
013A13FA  call        @ILT+215(__ftol2_sse) (13A10DCh) 
013A13FF  mov         dword ptr [x],eax 
    int y = static_cast<int>(d);
013A1402  fld         qword ptr [d] 
013A1405  call        @ILT+215(__ftol2_sse) (13A10DCh) 
013A140A  mov         dword ptr [y],eax 

显然,它完全相同!


1
这对我来说看起来不太性感 :) 一个性感的程序会完全使用SSE指令而不涉及FPU :) (我以为在VC中默认已经使用了SSE)。 - AnT stands with Russia
1
@AndreyT 是的 :) 回答中的代码是在调试模式下生成的。如果你尝试使用优化编译它,它会使用 SSE 指令。 - Khaled Alshaya
2
-1(如果我可以的话)。这并不明显。你的答案证明了它只在某些VS2008版本中是相同的。 - big-z
这是否与平台有关?不同的编译器可能会以不同的方式处理这两种类型的转换吗? - Frank Liu

4

没有任何区别。

当涉及到单个转换这样的基本结构时,一旦两个结构具有相同的语义意义,它们的性能将完全相同,并且为这些结构生成的机器代码将是相同的。


4

我认为实际结果是由实现定义的。您应该在您的编译器版本中进行检查。但我相信,在大多数现代编译器中,它会给出相同的结果。在C++中,您不应该使用C-cast,而应该使用C++ casts - 这将允许您在编译时发现错误。


性能问题并非实现定义(事实上,标准并未强制执行任何性能要求,除了容器操作的大O复杂度)。 - M.M

2

使用每种方法查看汇编代码,如果有差异,请使用分析器。


1

它们与编译时解决的相同,没有运行时开销。即使有一些差异,我也不会太在意这些微小(甚至不到微观)的优化。


0

正如大多数人所说,希望它们应该是相同的速度,尽管你要受编译器的支配...而这并不总是一个非常愉快的情况。继续阅读战争故事。

根据您的编译器和程序执行的处理器核心型号,float f; int i(f);float f; int i = (int)f;float f; int i = static_cast<int>(f); 等(包括涉及 double、long 和 unsigned 类型的变体)的速度可能非常慢 - 比您预期的要慢一个数量级。编译器可能会发出指令来改变内部处理器模式,导致指令流被丢弃。这实际上是编译器优化元素中的一个错误。我见过一些情况,在this analysis中提到了40个时钟周期的成本,此时您将面临一个重大的、意外的和令人恼火的性能瓶颈,而且没有完全令人满意、稳健、通用的解决方案。有一些使用汇编语言的替代方法,但据我所知,它们不能像转换一样将浮点数舍入为整数。如果有人知道更好的方法,请告诉我。我希望这个问题现在/将来很快就会被限制在遗留的编译器/硬件上,但您需要保持警惕。

附言:我无法访问那个链接,因为我的防火墙已经将其阻止,原因是与游戏相关,但是它的谷歌缓存足以证明作者比我更了解它。


-2

当你的选择对代码并没有太大影响时,我会选择那个看起来更熟悉、更容易被后来的程序员理解的选项。让代码更易于他人理解始终值得考虑。在这种情况下,出于这个原因,我会坚持使用int(…)


为什么您认为 int(...) 更常见呢?实际上,它在 C 中似乎无效,可能是 C++ 中的“伪构造函数”调用。而且,不明确转换类型,为什么会使代码更易于理解呢? - UncleBens
强制类型转换不是玩具,因此应该很容易识别。这就是C++风格的强制类型转换。 - foraidt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接