簡體   English   中英

為什么 unordered_map 的移動分配很慢?

[英]Why is move assignment of unordered_map slow?

我試圖了解移動/右值賦值運算符的工作原理。 我知道它在很大程度上是特定於實現的,但是假設unordered_map中的移動分配僅通過交換底層數據指針或大小屬性來工作,我想它應該非常快?

這是我嘗試運行的代碼:

#include <chrono>
#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include <unordered_map>
using namespace std;
 
void time_it(function<void()> f)
{
    auto start = chrono::steady_clock::now();
    f();
    auto end = chrono::steady_clock::now();
    auto diff = end - start;
    cout << chrono::duration<double, milli>(diff).count() << " ms" << endl;
}
 
using umap = unordered_map<string, string>;
static const size_t MAP_SIZE = 1000000;
 
int main()
{
    umap m;
    for (int i = 0; i < MAP_SIZE; i++)
    {
        auto s = to_string(i);
        m[s] = s;
    }
 
    time_it([&]() {
        cout << "copy\n";
        auto c = m;
    });
    time_it([&]() {
        cout << "move\n";
        auto c = move(m);
    });
}

它返回:

copy
204.4 ms
move
98.568 ms

為什么移動賦值運算符需要這么長時間(~100 ms)?

我使用g++ test.cpp -O3編譯。 這是我的g++ -v返回的內容:

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/6.3.0/lto-wrapper.exe
Target: mingw32
Configured with: ../src/gcc-6.3.0/configure --build=x86_64-pc-linux-gnu --host=mingw32 --with-gmp=/mingw --with-mpfr=/mingw --with-mpc=/mingw --with-isl=/mingw --prefix=/mingw --disable-win32-registry --target=mingw32 --with-arch=i586 --enable-languages=c,c++,objc,obj-c++,fortran,ada --with-pkgversion='MinGW.org GCC-6.3.0-1' --enable-static --enable-shared --enable-threads --with-dwarf2 --disable-sjlj-exceptions --enable-version-specific-runtime-libs --with-libiconv-prefix=/mingw --with-libintl-prefix=/mingw --enable-libstdcxx-debug --with-tune=generic --enable-libgomp --disable-libvtv --enable-nls
Thread model: win32
gcc version 6.3.0 (MinGW.org GCC-6.3.0-1)

正如 MilesBudnek 在他的評論中解釋的那樣,我只計算了unordered_map析構函數的運行時間(即 object c )在我的第二個time_it內部 ZC1C425268E68385D1AB5074F33Z 中

我將其更改為:

    time_it([&]() mutable {
        cout << "copy\n";
        auto c = m;
        m = c;
    });
    time_it([&]() mutable {
        cout << "move\n";
        auto c = move(m);
        m = move(c);
    });

使 c 的底層c不會被釋放,現在它說使用-O00.6 ms以不讓編譯器做不受歡迎的事情。

謝謝大家,真的很抱歉我在帖子中的錯誤!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM