转换大约150mb的字符串的快速方法

时间:2015-06-12 17:36:52

标签: c++ performance c++11

我一直试图通过char减少std::stringstream中的每个100值:

std::string str = stream.str();

auto decrement = [](char c) { return c - 100; };

std::string out;
out.reserve(str.size());
std::transform(str.begin(), str.end(), std::back_inserter(out), decrement);

stream = std::stringstream(out);

7分钟仍停留在std::transform指令上。对于 150mb 文本文件。

我没有使用优化版本。这是调试版本。目标是能够更快地运行代码以进行调试。此问题的发布结果是次要的。

有关如何提高效率的任何建议?

3 个答案:

答案 0 :(得分:16)

如果您不将str用于其他任何事情,我会考虑将其转换到位。这样,您可以回写到您读取的同一位置,并可能获得更好的缓存行为。只需更改

std::transform(str.begin(), str.end(), std::back_inserter(out), decrement);

std::transform(str.begin(), str.end(), str.begin(), decrement);

你可以完全摆脱你的out字符串。允许第3个(目标)参数与第一个参数相同。

这不仅完全消除了额外的150MB字符串变量,您以前必须访问内存中应该相当分开的两个不同位置。通过读取和写回同一个地方,您可以确保最大限度地使用缓存。

当然这会改变str,所以只有当你不需要原始的str变量时它才真正有用。

最终结果:

std::string str = stream.str();

auto decrement = [](char c) { return c - 100; };
std::transform(str.begin(), str.end(), str.begin(), decrement);
stream = std::stringstream(str);

答案 1 :(得分:5)

有两个明显的加速。

首先是就地改造。

std::string str = stream.str();

auto decrement = [=](char c) { return c -= 100; };

std::transform(str.begin(), str.end(), str.begin(), decrement);

stream = std::stringstream(str);
拉斐尔所涵盖的

第二个,只是因为你想要DEBUG优化速度,是绕过可能的调试迭代器检查。

std::string str = stream.str();

auto decrement = [=](char c) { return c -= 100; };

std::transform(&str[0], (&str[0])+str.size(), (&str[0]), decrement);

stream = std::stringstream(str);

这里我们用begin()替换&str[0]basic_string是指向字符缓冲区内容的原始指针。如果您使用的是非常奇怪的std::addressof,请使用&代替#navlist:hover #left-arrow { border-top: 10px solid white; position: relative; transform: translateX(120.2px) rotate(180deg); }

在一个带有调试工具的迭代器的系统中,这可能会快得多。在优化的构建中,我希望它具有相同的速度。

答案 2 :(得分:4)

如果您需要额外的速度(比Raphael提供的解决方案快约5倍),我认为仍然可以接受(也取决于您的目标机器)稍微不那么优雅(ss intrinsics(SSE2))。

#include <emmintrin.h>

__m128i dec = _mm_set1_epi8(100);
size_t x = 0;
for (; x < str.size()-15; x+=16)
{
    __m128i sse = _mm_loadu_si128((__m128i*)&str[x]);
    _mm_storeu_si128((__m128i*)&str[x], _mm_sub_epi8(sse, dec));
}

for (; x < str.size(); ++x)
    str[x] -= 100;