मैं बिटमैप पर टेक्स्ट प्रिंट करने के लिए windows.h "TextOutW" फ़ंक्शन का उपयोग कर रहा हूं। नियमित एएससीआई प्रिंटिंग वास्तव में तेज़ है, लेकिन यूनिकोड रेंज में प्रिंटिंग एक बड़ी मंदी का कारण बनती है। यहाँ एक यूनिकोड वर्ग मुद्रित करने और अवधि का परीक्षण करने के लिए मेरा कोड है:

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 बार प्रिंट करने में लगभग 5ms और 0x25A0 को 1000 बार प्रिंट करने में लगभग 50ms . का समय लगा

0
NO_GUI 4 मई 2021, 18:19

3 जवाब

सबसे बढ़िया उत्तर

आप यूनिस्क्राइब मार रहे हैं। ExtTextOutW और TextOutW जांचें कि क्या टेक्स्ट को यूनिस्क्राइब के माध्यम से थ्रेड किया जाना चाहिए या सीधे GDI को पास किया जाना चाहिए।

यूनिस्क्राइब ओवरहेड (अनुशंसित नहीं) से बचने के लिए आप ETO_IGNORELANGUAGE से ExtTextOutW तक पास कर सकते हैं, लेकिन आपको कुछ और उन्नत स्क्रिप्ट्स (CJK उर्फ ​​चीनी+जापान+कोरियाई, राइट टू लेफ्ट राइटिंग, कैरेक्टर बदलते आकार के आधार पर छूट जाएंगे) जहां उन्हें रखा गया है आदि) या बिल्कुल भी टेक्स्ट नहीं मिलता है।

0x25A0 कैरेक्टर के लिए मुझे लगभग 8× . स्लोडाउन मिलता है

0x6F22 के लिए मंदी 17× . तक बढ़ जाती है

मेरे सिस्टम पर, जब ETO_IGNORELANGUAGE निर्दिष्ट किया जाता है तो कोई मंदी नहीं होती है। 0x25A0 सही ढंग से प्रदर्शित होता है, 0x6F22 को डिफ़ॉल्ट बॉक्स से बदल दिया जाता है।

1
Daniel Sęk 5 मई 2021, 19:28

समस्या यह है कि आप एक वर्ण की ओर इशारा कर रहे हैं, न कि एक स्ट्रिंग की। wcslen अपरिभाषित व्यवहार प्रदर्शित कर रहा है और संभवत: बहुत बड़ी संख्या लौटा रहा है। इसे 1 से बदलें और चीजें बहुत तेज होनी चाहिए।

6
Mark Ransom 4 मई 2021, 18:24

यह कोई उत्तर नहीं है। मैं सिर्फ इस प्रश्न से समय की पुष्टि करने के लिए कोड पोस्ट करना चाहता हूं।

मुझे टिप्पणी किए गए पात्रों के लिए 7-8 एमएस मिल रहा है, और उस 0x25A0 के लिए ~ 50 एमएस।

मैं Times New Roman का उपयोग करता हूं क्योंकि इस पेज का दावा है कि इसमें वह यूनिकोड है प्रतीक।

#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;
}
1
Vlad Feinstein 5 मई 2021, 03:35