index vs iterator - 哪个会更高效?

时间:2018-01-25 18:41:01

标签: c++

我想知道如果我想迭代一个向量,下列哪种方法会更有效率。第一种选择:

int i;
for(i = 0; i<vector.size(); i++)
{
cout << vector[i];
}

OR

第二个选项:

vector<type>::iterator it;
for(it = vector.begin(); it != vector.end(); it++)
{
cout << *it;
}

2 个答案:

答案 0 :(得分:2)

通往地狱的道路铺好了意图;或者在我们的情况下过早优化。编译器完成的优化应使每个循环等效。让编译器为您工作,并在这种情况下专注于可读性和可维护性。正如其他人所指出的,dplyr是你的例子中的瓶颈,而不是循环本身。

如果您使用的是C ++ 11或更高版本,则range-based for loops非常适合易用性和可读性。

std::cout

否则,如果我需要知道元素的位置,我发现更容易使用for (const auto & element : myVector) { cout << element; } 和索引方法。如果我不关心这一点,那么我几乎总是使用vector::size()。在我看来,可读性对于任何一种方法都是等效的,迭代器是所有各种STL容器的更标准的方法。

答案 1 :(得分:1)

验证效率的一种方法是对代码进行计时,并在每个程序中运行压力测试。要为代码计时,请使用<chorno>头文件(C ++ 11)。

首先,创建一个向量,然后添加大量条目:

#include <vector>

// Create a stressed vector 
std::vector<int> myVector;

for (int i = 0; i < 10000; i++)
    myVector.push_back(i);

为了简化代码,我将把你的每个方法添加到一个函数中:

方法1

#include <vector>
#include <iostream>

void methodOne(std::vector<int> vector)
{
    for (int i = 0; i < int(vector.size()); i++)
        std::cout << vector[i] << std::endl; // don't forget to add a separation
}

方法2

#include <vector>
#include <iostream>

void methodTwo(std::vector<int> vector)
{
    for (auto it = vector.begin(); it != vector.end(); it++)
        std::cout << *it << std::endl; // don't forget to add a separation
}

我也想采用第三种方法,每种方法使用:

方法3

#include <vector>
#include <iostream>

void methodThree(std::vector<int> vector)
{
    for (auto element : vector)
        std::cout << element << std::endl;
}

现在,添加<chrono>标题,然后在main()中运行此例程,并创建Timer类,如Learn Cpp中所示:

计时器类

#include <chorno> 

class Timer
{
private: 
    // Type aliases to make accessing nested type easier
    using clock_t = std::chrono::high_resolution_clock;
    using second_t = std::chrono::duration<double, std::ratio<1> >;

std::chrono::time_point<clock_t> m_beg;

public:
    Timer() : m_beg(clock_t::now())
    {
    }

    void reset()
    {
        m_beg = clock_t::now();
    }

    double elapsed() const
    {
        return std::chrono::duration_cast<second_t>(clock_t::now() - m_beg).count();
    }
};

现在,对于main函数,只需运行以下代码:

主要

#include <vector>
#include <iostream>
#include <chrono>

int main()
{
    //Create a stressed vector
    std::vector<int> myVector;

    for (int i = 0; i < 10000; i++)
        myVector.push_back(i);

    Timer t;
    t.reset();
    t.reset();

    methodOne(myVector);
    auto t1 = t.elapsed();
    t.reset();

    methodTwo(myVector);
    auto t2 = t.elapsed();
    t.reset();

    methodThree(myVector);
    auto t3 = t.elapsed();

    std::cout << "\n";
    std::cout << "Time for Method 1 = " << t1 << " seconds\n";
    std::cout << "Time for Method 2 = " << t2 << " seconds\n";
    std::cout << "Time for Method 3 = " << t3 << " seconds\n";

    return 0;
}

以下是不同应力向量的代码输出:

条目数= 100:

Time for Method 1 = 0.146709 seconds 
Time for Method 2 = 0.176648 seconds  
Time for Method 3 = 0.16161 seconds

条目数量= 1000

Time for Method 1 = 1.67696 seconds
Time for Method 2 = 1.63569 seconds
Time for Method 3 = 1.64162 seconds

条目数= 3000

Time for Method 1 = 5.07384 seconds
Time for Method 2 = 5.01691 seconds
Time for Method 3 = 5.00742 seconds

条目数= 7000

Time for Method 1 = 11.8177 seconds
Time for Method 2 = 5.91258 seconds
Time for Method 3 = 3.52884 seconds

条目数= 15000

Time for Method 1 = 18.7798 seconds
Time for Method 2 = 8.2039 seconds
Time for Method 3 = 8.25364 seconds

所有这些测试均使用发行版x86执行。

在查看这些数字之后,我们可以得出结论,对于少数条目,任何一种方法都可以正常工作。但随着条目数量的增加,方法1似乎需要更多时间才能完成相同的任务,尽管我们正在考虑整合。也许其他变量类型可能会导致不同的结果。

话虽如此,我看到方法2和提议的方法3在处理巨大的循环和向量时更有效。

相关问题