0

假设我有一些代码多次调用诸如 vector::length() 之类的方法...确实创建了一个临时变量,例如

int length=myVector.length()

使其比多次调用该方法更有效?

这是一个有点假设的问题,所以让我们假设调用 vector::length() 是获得我们想要的结果的唯一方法。

4

5 回答 5

5

将值存储在局部变量中的成本几乎为零。调用内联的“获取此成员变量”的成本也几乎为零。

另一方面,如果对象不是向量,length也不保存在成员变量中,但必须进行计数 - 比如说 like strlen(),那么将其存储在局部变量中会有很大的好处。特别是如果字符串的长度超过几个字符。

另一个问题当然是您执行以下操作:

int number_of_widgets = my_widgets.length();
...   // more code here, but none that affect my_widgets. 

last_widget = my_widgets[number_of_widgets-1]; 
... 

然后其他人去编辑 cdoe:

int number_of_widgets = my_widgets.length();
... some code.
my_widgets.erase(some_widget_iterator);

...   // more code here

last_widget = my_widgets[number_of_widgets-1]; 
... 

现在您的代码正在访问有效范围之外,可能会崩溃和烧毁......

一如既往,魔鬼在细节中。如果您想知道您的代码中最快的是什么,请使用您的代码对其进行基准测试...

于 2013-02-10T23:05:27.610 回答
2

在这种情况下你不需要担心速度,直接调用length()会很快。为了可读性,除非您真的多次调用它,否则我会说 - 直接调用它。如果它确实使代码难看,例如在 10 行上调用 10 次,那么您可以将其缓存在一个变量中以使代码看起来更好。

优化规则 1:不要优化。反正很快。我认为 vector::length() 不会减慢您的程序,但无论如何,只要您没有速度问题,就没有充分的理由尝试手动优化它。如果相关,智能编译器应该决定并优化它。

在 IDE 上,您有代码完成功能,因此甚至不是输入更多内容的问题,只是代码的视觉可读性(同样,除非这个特定功能会减慢程序速度,我对此表示怀疑)。

于 2013-02-10T23:02:58.807 回答
1

唯一可以确定的方法是分析您的代码。

就个人而言,如果我知道向量在当前范围内不会改变,我会首先优化可读性,并在需要时根据分析 进行任何调整:

const int number_of_widgets = myVector.size();

“我们应该忘记小的效率,比如大约 97% 的时间:过早优化是万恶之源”——Donald Knuth

于 2013-02-10T22:58:27.690 回答
0

真正的答案是,如果可以的话,你应该使用迭代器,因为它们通常更快,并且它们完全避免了这个问题(假设向量没有重新分配)。

您可能正在寻找的答案是:它通常在简单的情况下被优化掉,但并非总是如此。

于 2013-02-10T23:01:47.513 回答
0

我会假设它们都将被编译为相同的代码。但是假设不好,所以我尝试了一个测试程序。我首先编译:

#include <iostream>
#include <vector>

int main()
{
    int myints[] = {16,2,77,29};
    std::vector<int> myVector (myints, myints + sizeof(myints) / sizeof(int) );
    int length=myVector.size();
    std::cout << length << std::endl;
    std::cout << length*3 << std::endl;
    return 0;
}

这正确地给出了 4 和 12 的输出。然后我尝试了这个程序,我不使用变量“长度”。

#include <iostream>
#include <vector>

int main()
{
    int myints[] = {16,2,77,29};
    std::vector<int> myVector (myints, myints + sizeof(myints) / sizeof(int) );
    std::cout << myVector.size() << std::endl;
    std::cout << myVector.size()*3 << std::endl;
    return 0;
}

该程序还正确地给出了 4 和 12 的输出,并且做了完全相同的事情,但两者之间没有可变长度。我可以声明,使用编译标志 -O3 或 -O2 它们会给出完全相同的二进制代码。这是使用 gcc 编译器完成的。因此,这两种方法都不是更快,而且它们都使用相同数量的内存。

因此,只需使用看起来最好且最容易阅读的那个。

虽然我不确定我们是否可以从我的测试中完全概括,因为可能还有其他优化在起作用。例如,myVector.size() 可能在编译时计算为 4,因此可能已经硬编码到文件中,而不是在运行时计算出来。这将使我的测试毫无意义。

希望这可以帮助。(虽然我在写这篇文章时可以看到其他 4 个答案)所以其他人可能已经在测试这个方面做得更好。

于 2013-02-10T23:20:12.300 回答