c++ - 使用 vector 时是无符号整数还是迭代器?

标签 c++ iterator

我目前正在和一些 friend 一起做一个 C++ 学校项目。

当我在 C++ 中使用 vector 之前,我做了类似这样的事情来使用它们:

unsigned int i = 0;
while (i != myVector.size())
{
    doSomething(myVector[i]);
    i++;
}

但是在这个项目中,我的 friend 们看到我使用这样的 vector 并不高兴,并要求我使用迭代器。 我不是很喜欢迭代器,因为它们的语法很难记住,但我的 friend 们说使用它们更好,因为它工作得更快。 由于我们在一个包含大量 vector 的大项目中工作,因此使用迭代器至关重要。

时间过去了,我仍在使用它们,即使我仍然不记得它们的语法,但我想看看迭代器方法是否真的比“unsigned int”方法更快。

所以我制作了这两个程序:

第一个使用 unsigned int 方法的程序:

#include <vector>
#include <string>
#include <iostream>

int main()
{
    std::string str = "This is a string";

    int i = 0;
    std::vector<std::string> vec;

    while (i != 10000000)
    {
        vec.push_back(str);
        i++;
    }

    unsigned int j = 0;
    while (j != vec.size())
    {
        std::cout << vec[j] << std::endl;
        j++;
    }
    return (0);
}

第二个程序使用迭代器方法:

#include <vector>
#include <string>
#include <iostream>

int main()
{
    std::string str = "This is a string";

    int i = 0;
    std::vector<std::string> vec;

    while (i != 10000000)
    {
        vec.push_back(str);
        i++;
    }

    std::vector<std::string>::iterator it;
    it = vec.begin();
    while (it != vec.end())
    {
        std::cout << *it << std::endl;
        it++;
    }
    return (0);
}

如您所见,这两个程序都将首先创建一个大小为 10 000 000 的 vector (我放了一个大尺寸,这样如果时间上有差异,它会更容易被注意到)然后我将打印 vector 中的字符串,但使用两种不同的方法。

我在linux上用time来知道每个程序的执行时间是这样的:

time ./a.out

结果如下:

无符号整型方法:

real    0m39,391s
user    0m5,463s
sys     0m21,108s

迭代器方法:

real    0m39,436s
user    0m5,972s
sys     0m20,652s

而且…………是同一时间?! 两者之间只有不到 1 秒的差异,可以忽略不计,而且它是一个包含 1000 万个字符串的 vector 。

所以我想知道这两种方法之间是否真的有区别,迭代器真的更好用吗?

最佳答案

使用迭代器的主要原因不是性能,而是出错的可能性更小和代码更具表现力。对比一下

unsigned int i = 0;
while (i != myVector.size())
{
    doSomething(myVector[i]);
    i += 2;
}

unsigned int start = myVector.size() + 42;

for (unsigned int i = start; i != myVector.size(); ++i){
    doSomething(myVector[i]);
}

for (const auto& e : myVector) {
     doSomething(e);
}

基于范围的 for 循环使迭代器的使用尽可能简单(您甚至看不到迭代器,但它们在幕后使用)。当您手动管理索引时,有数百万种方法会出错,使用迭代器可能有 2 或 3 种。

对于您的性能比较:由于 vector 将其元素存储在连续的内存中,因此 vector 迭代器可以是普通指针。您认为的开销主要是语法糖,使您能够编写更好的代码。因此,您看不出太大差异也就不足为奇了。

附言

i used it a lot i am kinda confident of not making too much mistakes

用整数来迭代数组是上个世纪的事了。它不安全,导致很难检测到错误,并且很容易调用未定义的行为。编写代码来表达你想做什么,而不是指示你的处理器。如果你想为 vector 的每个元素做一些事情,你应该使用基于范围的 for 循环或旧的 std::for_each :

std::for_each(myVector.begin(),myVector.end(),doSomething);

它没有手动使用索引的任何缺点(您发现上述循环中的错误了吗?)并且具有无论 myVector 实际上是什么容器看起来都一样的优点它包含什么类型的元素,或者 doSomething 实际上是什么(它可以是一个自由函数、一个仿函数、一个 lambda,由您选择)。

关于c++ - 使用 vector 时是无符号整数还是迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53547485/

相关文章:

c++ - 将 vector 迭代器传递给模板函数

c++ - 如何通过迭代器将 map<string, int> push_back 到 vector<map<string, int>> 中?

c++ - std::list 和 std::for_each:我的终点在哪里?

c++ - 我可以在 Arduino 的库文件夹之外安装一个库吗?

C++11:std::vector::shrink_to_fit 复杂度

c++ - std::unique_lock::release 的用例是什么?

php - 为什么 ArrayIterator 子类的构造函数从未被调用?

java - Java 中的不可变对象(immutable对象)和访问数据

c++ - 让一个引用成员引用另一个成员是否合法?

c++ - Perl 系统调用导致核心转储但 $?保持为零