什么更快,内联函数调用或哈希图查找

What's faster, an inline function call or a hashmap lookup

本文关键字:函数调用 哈希图 查找 什么      更新时间:2023-10-16

假设我有一个类ClassToSort,我需要根据valsecondVal的值(按(val * 100) + secondVal的升序(对std::sort()进行排序。

class ClassToSort {
  private:
    int val;
    long int secondVal;
    int id;
  public:
    inline const int getVal() const { return val; }
    inline const long int getSecondVal() const { return secondVal; }
    inline const int getID() const { return id; }
};
std::vector<ClassToSort*> objs;

现在,我有两种方法对其进行排序,要么预先计算 (val * 100) + secondVal 的值并将其存储在std::unordered_map<int, long> valMap中并在排序时引用此映射,要么在排序时每次对getVal()getSecondVal()进行函数调用(这将导致函数调用次数翻倍(。以下是两个选项:

std::sort(objs.begin(), objs.end(),
         [&](const ClassToSort* first, const ClassToSort* second) {
          return valMap[first->getID()] < valMap[second->getID()];
         });

std::sort(objs.begin(), objs.end(),
         [](const ClassToSort* first, const ClassToSort* second) {
          return (first->getVal() * 100 + first->getSecondVal()) <
                 (second->getVal() * 100 + second->getSecondVal());
         });

很明显,第二个选项不仅会为每个对象调用两次 getter 函数,而且还会执行两次相同的计算。直观地说,我认为对于大量输入,哈希表查找会比函数调用次数更多时更快,同时重新计算。我的理解正确吗?

大多数时候,直接函数调用会自动内联。

示例中的复杂性不在于您两次调用"getter",而是多次进行计算 - 用于与特定元素的所有比较。

使用 unordered_map您还必须首先创建哈希表。

看看这些基准。

直接使用成员与使用 getter 函数没有区别。
哈希查找的速度是每次比较计算的 10 倍。
如果您必须多次排序,则通过将计算值(缓存(存储为一对(作为哈希映射的更便宜的替代方案(来保留计算值(缓存(可能会很有用。

使用指向类的指针而不是值可能会改变性能(更糟(,但它不应该改变观察到的差异。