通过内联降低抽象层的成本

Reduce the cost of abstraction layer by inlining

本文关键字:抽象      更新时间:2023-10-16

在我的项目中,我有一些像这样的抽象层:

 Vector3 normalizeVector(Vector3 v);
 Vector3 vectorMultiplyMatrix(Vector3 v, Matrix3 m);

它们只是平台特定数学库(如DirectXMath)的"代理"函数。

我的问题是如何降低这些层的成本?通过使所有这些函数内联,调用它们而不是直接调用特定于平台的函数的成本是否会完全消除?

谢谢

添加一个新抽象层(代理、facade等)的成本可以忽略不计,因为它将一堆函数调用捆绑在另一个抽象层中。将数据传递给它们的方式可能会给您带来麻烦,特别是在使用复杂对象、容器等时。

Vector3 normalizeVector(Vector3 v);

在每次调用时创建传递的Vector3对象的副本。如果您面临性能问题,那么通过将按值传递更改为按const reference传递来避免创建副本:

Vector3 normalizeVector(const Vector3& v);

这个函数的新原型表示:"我需要一个对现有的有效Vector3对象的引用,我将使用但不更改"

除非你真的面临性能问题,否则不要优化你的代码。过早的优化一直都是邪恶的,而且永远都是。

暴露函数体将给编译器一个机会通过内联消除函数调用。

它是否会真正使用它取决于它的内部启发式:内联可能会扩大生成代码的总体大小,使其不太适合缓存,并最终抵消消除调用的好处。

有一些特殊的关键字(例如vc++中的__forceinline)可以用来覆盖编译器的成本/收益分析,但是编译器在这类决策上往往比程序员更正确!

使用配置文件引导的优化可以帮助编译器根据程序的实际使用模式做出更好的优化决策,包括哪些函数是"热"的,可以内联,哪些是"冷"的,应该被单独保留。


要记住的一个特别强大的技术是模板元编程。其思想是将尽可能多的计算推到编译时。