gpt4 book ai didi

c++ - 为什么 std::u16string 比 char16_t 数组慢?

转载 作者:IT老高 更新时间:2023-10-28 23:10:32 24 4
gpt4 key购买 nike

经过一些性能实验,似乎使用 char16_t 数组有时可以将性能提高 40-50%,但似乎使用 std::u16string 而不进行任何复制和分配应该与 C 数组一样快。然而,基准测试显示相反。

这是我为基准测试编写的代码(它使用 Google Benchmark 库):

#include "benchmark/benchmark.h"
#include <string>

static std::u16string str;
static char16_t *str2;

static void BM_Strings(benchmark::State &state) {
while (state.KeepRunning()) {
for (size_t i = 0; i < str.size(); i++){
benchmark::DoNotOptimize(str[i]);
}
}
}

static void BM_CharArray(benchmark::State &state) {
while (state.KeepRunning()) {
for (size_t i = 0; i < str.size(); i++){
benchmark::DoNotOptimize(str2[i]);
}
}
}

BENCHMARK(BM_Strings);
BENCHMARK(BM_CharArray);

static void init(){
str = u"Various applications of randomness have led to the development of several different methods ";
str2 = (char16_t *) str.c_str();
}

int main(int argc, char** argv) {
init();
::benchmark::Initialize(&argc, argv);
::benchmark::RunSpecifiedBenchmarks();
}

显示如下结果:

Run on (8 X 2200 MHz CPU s)
2017-07-11 23:05:57
Benchmark Time CPU Iterations
---------------------------------------------------
BM_Strings 1832 ns 1830 ns 365938
BM_CharArray 928 ns 926 ns 712577

我在 mac 上使用 clang(Apple LLVM 版本 8.1.0 (clang-802.0.42))。启用优化后,差距更小但仍然很明显:

 Benchmark             Time           CPU Iterations
---------------------------------------------------
BM_Strings 242 ns 241 ns 2906615
BM_CharArray 161 ns 161 ns 4552165

有人可以解释这里发生了什么以及为什么会有所不同吗?

更新(混合顺序并添加了一些热身步骤):

Benchmark             Time           CPU Iterations
---------------------------------------------------
BM_CharArray 670 ns 665 ns 903168
BM_Strings 856 ns 854 ns 817776
BM_CharArray 166 ns 166 ns 4369997
BM_Strings 225 ns 225 ns 3149521

还包括我正在使用的编译标志:

/usr/bin/clang++ -I{some includes here} -O3 -std=c++14 -stdlib=libc++ -Wall -Wextra -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -O3 -fsanitize=address -Werror -o CMakeFiles/BenchmarkString.dir/BenchmarkString.cpp.o -c test/benchmarks/BenchmarkString.cpp

最佳答案

由于 libc++ 实现小字符串优化的方式,在每次取消引用时,它都需要检查字符串内容是存储在字符串对象本身还是堆中。因为索引被包装在 benchmark::DoNotOptimize 中,所以每次访问字符时都需要执行此检查。通过指针访问字符串数据时,数据始终是外部的,因此不需要检查。

关于c++ - 为什么 std::u16string 比 char16_t 数组慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45043742/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com