【问题标题】:Multi-threading with boost unordered hash map具有提升无序哈希映射的多线程
【发布时间】:2014-03-16 10:01:42
【问题描述】:

我有一个程序,它逐行读取文件,对该行进行哈希处理并将其存储在 boost 无序哈希映射中(如下所示)。但是,我已经意识到这段代码是我程序中的一个瓶颈,因为文件可能会变得非常庞大。

    typedef boost::unordered_map<std::string,std::string> MAP;
    MAP hash_table;

    FILE *stream = fopen(filename, "r");
    char *line;

    while(fscanf(stream, " %m[^\n]", &line) == 1)
    {

            hash_table[line].push_back(line);
    } 

我计划创建多个线程,每个线程负责读取和散列文件的一部分。我读过 boost 无序映射是线程不安全的。如何在下面的代码中合并互斥锁。我能否只锁定当前正在修改的存储桶而不是整个哈希映射?

【问题讨论】:

    标签: multithreading boost mutex


    【解决方案1】:

    您提到这对您来说是一个性能瓶颈。鉴于此,我将为您提供一些与互斥锁无关的性能提示,因为我认为线程只会让事情变得更糟。

    鉴于您的键和值完全相同 (line),请使用 unordered_set 并节省大约一半的存储空间。

    您正在使用特殊的 scanf 格式 %m。这会动态分配您必须释放的内存。但是你没有释放,所以你在泄漏。此外,在 scanf 期间分配然后复制到 std::string 再次分配是浪费时间。最好存储 fscanf 直接分配的内容(在使用哈希表时释放)。

    您正在散列整个字符串。如果您对将要阅读的行有所了解,则可以加快速度。例如,只对每行的前十个字符进行哈希处理。

    一旦这些东西被清理干净,你的瓶颈很可能就是文件系统。

    【讨论】:

    • 感谢您的提示。我尝试将哈希表定义更改为 boost::unordered_map MAP 并计算了所用时间。我没有注意到所花费的总时间有任何变化。我需要为 fopen 方法指定任何缓冲区大小吗?
    • 不,您不需要指定缓冲区大小。要知道我们是否可以让这更快,我们需要知道消耗了多少 CPU 时间与实际(墙)时间。如果你在 *nix 上,运行time myprog(myprog 当然是你的可执行文件,加上它需要的任何参数)。告诉我们那是什么意思。
    猜你喜欢
    • 1970-01-01
    • 2011-03-14
    • 2017-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多