如何加快打印 Unicode?

How To Speed Up Printing Unicode?

我正在使用 windows.h“TextOutW”函数将文本打印到位图。打印常规 ascii 确实很快,但是使用 unicode 运行ge 打印似乎会导致速度大幅下降。这是我打印 unicode 方块并测试持续时间的代码:

wchar_t b = 0x25A0;
LPCWSTR s = &b;
TextOutW(hMyDC, x, y, s, wcslen(s));

有什么方法可以加快速度吗?

编辑: 我 运行 我的循环有一个定时器来测试速度:

    using std::chrono::high_resolution_clock;
    using std::chrono::duration_cast;
    using std::chrono::duration;
    using std::chrono::milliseconds;



auto t1 = high_resolution_clock::now();

for(int i = 0; i<1000; i++){
    TextOutW(hMyDC, 25, 25, s, 1);
}
  
auto t2 = high_resolution_clock::now();

  //  auto ms_int = duration_cast<milliseconds>(t2 - t1);
duration<double, std::milli> ms_double = t2 - t1;
    cout << ms_double.count() << "ms\n";

打印 'H' 1000 次大约需要 5 毫秒 打印 0x25A0 1000 次大约需要 50 毫秒

问题是您指向的是单个字符,而不是字符串。 wcslen 表现出未定义的行为并且可能返回一个非常大的数字。将其替换为 1,事情应该会大大加快。

这不是答案。我只想post代码来确认这个问题的时间。

对于注释掉的字符,我得到 7-8 毫秒,对于那些 0x25A0

,我得到 ~50 毫秒

我使用 Times New Roman 因为 this page 声称它有那个 UNICODE 符号。

#include <iostream>
#include <chrono>
#include <windows.h>

int main()
{
    wchar_t b = 0x25A0;
    //wchar_t b = 0x0416;
    //wchar_t b = L'H';

    LPCWSTR s = &b;
    HDC hDC = ::GetWindowDC(::GetDesktopWindow());
    HFONT hFont = CreateFontW(36, 20, 0, 0, FW_DONTCARE, FALSE, TRUE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
        CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, L"Times New Roman");
    HGDIOBJ hOld = ::SelectObject(hDC, hFont);
    auto t1 = std::chrono::steady_clock::now();
    for (int i = 0; i < 1000; i++) {
        TextOutW(hDC, 25, 25, s, 1);
    }
    auto t2 = std::chrono::steady_clock::now();

    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() << " msec" << std::endl;
    return 0;
}

您正在点击 Uniscribe。 ExtTextOutWTextOutW 检查文本是应该通过 Uniscribe 串接还是直接传递给 GDI。

为避免 Uniscribe 开销(不推荐),您可以将 ETO_IGNORELANGUAGE 传递给 ExtTextOutW,但您会错过一些更高级的脚本(CJK 又名中文+日本+韩文,从右到左书写,字符根据放置位置改变形状等)或根本没有文本。

对于 0x25A0 字符,我得到大约 8×

的减速

对于 0x6F22 减速增加到 17×

在我的系统上,当指定 ETO_IGNORELANGUAGE 时没有减速。 0x25A0显示正确,0x6F22被默认框替换。