c++ - 查找整数值计数的最快方法 (C++)

标签 c++ performance c++11

我需要一个无符号整数列表中每个出现值的出现次数。 IE。如果传递序列 [ 3, 6, 9, 3, 9 ] 我想要 [ { 3, 2}, {6, 1}, {9, 2} ]。

这些值是随机的 32 位无符号整数(范围为 1 到 1,000,000,000)。结果可以存储在任何数据结构中(只要它们可以线性迭代),虽然排序的值是理想的,但这是速度之后的次要问题。

目前我有-

T UniqueCount(std::vector<unsigned> &A)
{
    std::unordered_map<unsigned,unsigned> value_counts;

    for(unsigned val : A) {
        value_counts[val]++;
    }

    A.clear();

    ...
}

分析显示 std::unordered_map 比 std::map 更快。

有更好的方法吗?/更快的方式?值得注意的是,用例 (count > 4) 可以记录为 4。

目前这是一个瓶颈,因此虽然标准容器是首选,但如果性能提升值得额外的维护成本,则可以考虑定制容器。

最佳答案

在我的系统(Win10 x64,MSVC daily package x64 发布版本)上,使用输入 vector 中的 100,000 个随机未排序值进行测试,以下使用 std::sort + std::adjacent_find 使用 std::unordered_map 和@krzaq 答案中的代码(现在在 OP 中)在 ~10ms 与 ~27ms 之间执行:

std::vector<std::pair<unsigned, unsigned>> unique_count(std::vector<unsigned>& a) {
    auto it = begin(a);
    auto const last = end(a);

    std::vector<std::pair<unsigned, unsigned>> value_counts;
    std::sort(it, last);
    while (it != last) {
        auto const prev = it;
        it = std::adjacent_find(it, last, std::not_equal_to<unsigned>{});
        if (it != last) {
            ++it;
        }
        value_counts.emplace_back(*prev, static_cast<unsigned>(it - prev));
    }
    return value_counts;
}

Online Demo

经验教训:缓存一致性通常胜过算法的复杂性。

关于c++ - 查找整数值计数的最快方法 (C++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40698693/

相关文章:

python - 以最快的方式确定 Python 数组中每组重复值的索引

c++ - 如何使用线程处理标准容器?

C++ 软件设计选项,类关系

c++ - Base 64 编码丢失数据

mysql - 编写查询以连接并获取 mySql 中所有行的总和

java - java中创建类什么时候有利

c++ - 友元定义函数的命名空间是什么?

c++ - 与 `std::chrono` 类型相比,为什么使用 `float` 进行时差测量会给出更多有效数字的 `double` 类型?

c++ - 如何判断 .cpp 文件在哪个项目中

C++ 类委托(delegate)构造函数问题