简体   繁体   中英

Why C++ standard string copy is faster than string move?

Thought string copy operation should be slower than move, but the benchmark shows it's faster.

static void StringCreationMove(benchmark::State & state) {
    std::string x = "hello";
    for (auto _ : state) {
        std::string created_string_move(std::move(x));
        benchmark::DoNotOptimize(created_string_move);
    }
}
BENCHMARK(StringCreationMove);

static void StringCreationCopy(benchmark::State & state) {
    std::string x = "hello";
    for (auto _ : state) {
        std::string created_string_copy(x);
        benchmark::DoNotOptimize(created_string_copy);
    }
}
BENCHMARK(StringCreationCopy);

If move doesn't allocate memory, why it's slow? Or maybe something is wrong in this benchmark it self.

UPDATE

The updated version may reflect more insights.

#include <benchmark/benchmark.h>

static void StringCreationMove(benchmark::State & state) {
    for (auto _ : state) {
        std::string x = "hello";
        benchmark::DoNotOptimize(x);
        std::string created_string_move(std::move(x));
        benchmark::DoNotOptimize(created_string_move);
    }
}
BENCHMARK(StringCreationMove);

static void StringCreationCopy(benchmark::State & state) {
    for (auto _ : state) {
        std::string x = "hello";
        benchmark::DoNotOptimize(x);
        std::string created_string_copy(x);
        benchmark::DoNotOptimize(created_string_copy);
    }
}
BENCHMARK(StringCreationCopy);

BENCHMARK_MAIN();

Result on my MacBook Air 2013.

Run on (4 X 1300 MHz CPU s)
CPU Caches:
  L1 Data 32 KiB (x2)
  L1 Instruction 32 KiB (x2)
  L2 Unified 256 KiB (x2)
  L3 Unified 3072 KiB (x1)
Load Average: 1.51, 1.49, 1.74
-------------------------------------------------------------
Benchmark                   Time             CPU   Iterations
-------------------------------------------------------------
StringCreationMove       72.0 ns         67.6 ns     11394713
StringCreationCopy       47.1 ns         47.1 ns     14960781

The benchmark results are different if you use the standard libstd++ (GNU) or libc++ (llvm). The last gives the moving is faster: https://quick-bench.com/q/DV-lRSuipynW2QilZZvCV91uWHY “你好”+ LLVM 标准 C++ 库

As for the answer to your question. The string "hello" is too short and the small string optimization is applied. It means a small array is used for small strings, so there is no advantage of the moving. It depends on the implementation, but probably GNU std::string does not optimally copy the array's data when moving performed. If you use long enough strings, the moving is always faster.

GNU: https://quick-bench.com/q/QFlfvUJ_Rua6g95koevFZsNaLrg “早上好,世界!圣诞快乐!” + GNU 标准 C++ 库 LLVM: https://quick-bench.com/q/iJgfzrWc3yNUMkBYnbPI02e1lW4 “早上好,世界!圣诞快乐!” + LLVM 标准 C++ 库

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM