gpt4 book ai didi

c++ - utf8 <-> utf16 : codecvt poor performance

转载 作者:可可西里 更新时间:2023-11-01 15:54:54 25 4
gpt4 key购买 nike

我正在研究我的一些旧的(并且专门面向 win32 的)东西并考虑使它更现代/可移植 - 即在 C++11 中重新实现一些可广泛重用的部分。这些部分之一是 utf8 和 utf16 之间的转换。在 Win32 API 中,我正在使用 MultiByteToWideChar/WideCharToMultiByte,尝试使用此处的示例代码将这些内容移植到 C++11:https://stackoverflow.com/a/14809553 .结果是

发布版本(由 MSVS 2013 编译,在 Core i7 3610QM 上运行)

stdlib                   = 1587.2 ms
Win32 = 127.2 ms

调试构建

stdlib                   = 5733.8 ms
Win32 = 127.2 ms

问题是 - 代码有问题吗?如果一切似乎都正常 - 是否有充分的理由造成这种性能差异?

测试代码如下:

#include <iostream>
#include <fstream>
#include <string>
#include <iterator>
#include <clocale>
#include <codecvt>

#define XU_BEGIN_TIMER(NAME) \
{ \
LARGE_INTEGER __freq; \
LARGE_INTEGER __t0; \
LARGE_INTEGER __t1; \
double __tms; \
const char* __tname = NAME; \
char __tbuf[0xff]; \
\
QueryPerformanceFrequency(&__freq); \
QueryPerformanceCounter(&__t0);

#define XU_END_TIMER() \
QueryPerformanceCounter(&__t1); \
__tms = (__t1.QuadPart - __t0.QuadPart) * 1000.0 / __freq.QuadPart; \
sprintf_s(__tbuf, sizeof(__tbuf), " %-24s = %6.1f ms\n", __tname, __tms ); \
OutputDebugStringA(__tbuf); \
printf(__tbuf); \
}

std::string read_utf8() {
std::ifstream infile("C:/temp/UTF-8-demo.txt");
std::string fileData((std::istreambuf_iterator<char>(infile)),
std::istreambuf_iterator<char>());
infile.close();

return fileData;
}

void testMethod() {
std::setlocale(LC_ALL, "en_US.UTF-8");
std::string source = read_utf8();
{
std::string utf8;

XU_BEGIN_TIMER("stdlib") {
for( int i = 0; i < 1000; i++ ) {
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert2utf16;
std::u16string utf16 = convert2utf16.from_bytes(source);

std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert2utf8;
utf8 = convert2utf8.to_bytes(utf16);
}
} XU_END_TIMER();

FILE* output = fopen("c:\\temp\\utf8-std.dat", "wb");
fwrite(utf8.c_str(), 1, utf8.length(), output);
fclose(output);
}

char* utf8 = NULL;
int cchA = 0;

{
XU_BEGIN_TIMER("Win32") {
for( int i = 0; i < 1000; i++ ) {
WCHAR* utf16 = new WCHAR[source.length() + 1];
int cchW;
utf8 = new char[source.length() + 1];

cchW = MultiByteToWideChar(
CP_UTF8, 0, source.c_str(), source.length(),
utf16, source.length() + 1);

cchA = WideCharToMultiByte(
CP_UTF8, 0, utf16, cchW,
utf8, source.length() + 1, NULL, false);

delete[] utf16;
if( i != 999 )
delete[] utf8;
}
} XU_END_TIMER();

FILE* output = fopen("c:\\temp\\utf8-win.dat", "wb");
fwrite(utf8, 1, cchA, output);
fclose(output);

delete[] utf8;
}
}

最佳答案

在我自己的测试中,我发现对 wstring_convert 的构造函数调用具有巨大的开销,至少在 Windows 上是这样。正如其他答案所暗示的那样,您可能很难击败 native Windows 实现,但请尝试修改您的代码以在循环之外构造转换器。我希望您会看到 5 到 20 倍的改进,尤其是在调试版本中。

关于c++ - utf8 <-> utf16 : codecvt poor performance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26196686/

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