c++ - STL中关联数组(map)的速度

标签 c++ stl

<分区>

写了一个简单的程序来测量STL的速度。以下代码显示在我的 Corei7-2670QM PC(2.2GHz 和 Turbo 3.1GHz)上花费了 1.49 秒。如果我删除循环中的 Employees[buf] = i%1000; 部分,它只需要 0.0132 秒。所以散列部分用了 1.48 秒。为什么这么慢?

#include <string.h>
#include <iostream>
#include <map>
#include <utility>
#include <stdio.h>
#include <sys/time.h>
using namespace std;

extern "C" {
int get(map<string, int> e, char* s){
    return e[s];
}
int set(map<string, int> e, char* s, int value) {
    e[s] = value;
}
}

double getTS() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec + tv.tv_usec/1000000.0;
}

int main()
{
    map<string, int> Employees;
    char buf[10];
    int i;
    double ts = getTS();
    for (i=0; i<1000000; i++) {
        sprintf(buf, "%08d", i);
        Employees[buf] = i%1000;
    }
    printf("took %f sec\n", getTS() - ts);
    cout << Employees["00001234"] << endl;
    return 0;
}

最佳答案

这是您的代码的 C++ 版本。请注意,在 get/set 中传递 map 时,您应该显然通过引用获取 map 。

更新 更进一步,认真优化给定的测试用例:

Live On Coliru

#include <iostream>
#include <boost/container/flat_map.hpp>
#include <chrono>
using namespace std;

using Map = boost::container::flat_map<string, int>;

int get(Map &e, char *s) { return e[s]; }
int set(Map &e, char *s, int value) { return e[s] = value; }

using Clock = std::chrono::high_resolution_clock;

template <typename F, typename Reso = std::chrono::microseconds, typename... Args> 
Reso measure(F&& f, Args&&... args) {
    auto since = Clock::now();
    std::forward<F>(f)(std::forward<Args>(args)...);
    return chrono::duration_cast<Reso>(Clock::now() - since);
}

#include <boost/iterator/iterator_facade.hpp>

using Pair = std::pair<std::string, int>;

struct Gen : boost::iterators::iterator_facade<Gen, Pair, boost::iterators::single_pass_traversal_tag, Pair>
{
    int i;
    Gen(int i = 0) : i(i) {}

    value_type dereference() const { 
        char buf[10];
        std::sprintf(buf, "%08d", i);
        return { buf, i%1000 }; 
    }
    bool equal(Gen const& o) const { return i==o.i; }
    void increment() { ++i; }
};

int main() {
    Map Employees;
    const auto n = 1000000;

    auto elapsed = measure([&] {
            Employees.reserve(n);
            Employees.insert<Gen>(boost::container::ordered_unique_range, {0}, {n});
        });

    std::cout << "took " << elapsed.count() / 1000000.0 << " sec\n";

    cout << Employees["00001234"] << endl;
}

打印

took 0.146575 sec
234

旧答案

这只是在适当的地方使用了 C++

Live On Coliru

#include <iostream>
#include <map>
#include <chrono>
#include <cstdio>
using namespace std;

int get(map<string, int>& e, char* s){
    return e[s];
}
int set(map<string, int>& e, char* s, int value) {
    return e[s] = value;
}

using Clock = std::chrono::high_resolution_clock;

template <typename Reso = std::chrono::microseconds>
Reso getElapsed(Clock::time_point const& since) {
    return chrono::duration_cast<Reso>(Clock::now() - since);
}

int main()
{
    map<string, int> Employees;
    std::string buf(10, '\0');

    auto ts = Clock::now();
    for (int i=0; i<1000000; i++) {
        buf.resize(std::sprintf(&buf[0], "%08d", i));
        Employees[buf] = i%1000;
    }
    std::cout << "took " << getElapsed(ts).count()/1000000.0 << " sec\n";
    cout << Employees["00001234"] << endl;
}

打印:

took 0.470009 sec
234

关于c++ - STL中关联数组(map)的速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28547901/

相关文章:

c++ - 当你有一个虚拟析构函数时,基类指针中的 "delete this"会删除派生类对象吗?

c++ - 如何使用 STL 容器来保存基于模板的 shared_ptr?

c++ - 对容器中所有元素的成员函数结果求和的最佳方法是什么?

c++ - 写入二进制 VTK 文件时出错

c++ - 如何检查weak_ptr是否为空(未分配)?

c++ - 从代码创建的 QPushButton 的最小尺寸/宽度

c++ - SGI STL 子分配空闲列表

c++ - C++中一组分组数据的数据结构

c++ - 选择合适的 STL 容器来记录数据

c++ - 如何删除重复项并仅保留列表中的唯一指针?