使用std :: wcout

时间:2018-07-15 01:51:09

标签: c++ windows cout

我试图用C ++重新创建Windows Reg.exe实用工具。具体来说,是在REG.exe中完成以下命令所附带的功能。

REG QUERY "HKLM\Software" /s

但是,当我将结果输出到屏幕时,我似乎遇到了严重的瓶颈。

如果我将std::wcout << fPath.c_str()注释掉,则该程序将在1.45分钟内完成,而不是在20分钟内完成注释。

我想知道为什么会这样,如何解决。

inline void show(HKEY aHkey, std::wstring aHkeyPath, std::wstring aSubKey, RegValue &aValueData, bool aDisplayPath, bool aDisplayValue, bool aLastItem)
{
    if (aDisplayValue)
    {
        // Show registry value name
        std::wstring lValueName = (aValueData.lValueName);
        if (lValueName == TEXT("")) lValueName = TEXT("(Default)");

        // Recover from non ascii characters
        if (!std::wcout.good())
        {
            std::wcout.clear();
        }

        // Show registry type
        std::wstring lDataType = convertToWstr(getDataTypeStringName(aValueData.lRegType));
        std::wstring lDataValue;

        // Show registry data
        if (lDataType == L"REG_DWORD" ||
            lDataType == L"REG_QWORD" ||
            lDataType == L"REG_DWORD_LITTLE_ENDIAN" ||
            lDataType == L"REG_QWORD_LITTLE_ENDIAN" ||
            lDataType == L"REG_DWORD_BIG_ENDIAN")
        {
            lDataValue = L"0x0" + (aValueData.lDataValue);
        }
        else
        {
            lDataValue = (aValueData.lDataValue);
        }


        std::wstring fPath = lValueName + L"    " + lDataType + L"    " + lDataValue;

        std::wcout << fPath.c_str();
    }
    std::cout << "\n";
}

Reg值结构

   struct RegValue
   {
       std::wstring lValueName;
       unsigned int lRegType;
       std::wstring lDataValue;
   };

主体调用功能

RegValue lRegValueData;
std::wstring lCurrentSubKey = L"";
std::wstring lCurrentValue = L"";
unsigned int lMatchTotal = 0;

// HACK: Makes sure that lSubKeyList loop will be entered even if there is no sub keys
// Additionally, allows for the last subkey within the dequeue to be shown
lSubKeyList.push_back(L"End");

while (lSubKeyList.size())
{
    //show(hkey, lHkeyPath, lCurrentSubKey, lRegValueData, true, false, false);

    while (lValueList.size())
    {
        lCurrentValue = lValueList.front();
        lValueList.pop();
        lResult = getValueData(hkey, lHkeyPath, lCurrentSubKey, lCurrentValue, lRegValueData);

        if (lResult != ERROR_SUCCESS)
        {
            error(lResult);
            return false;
        }

        if (lFind || lFilterDataType)
        {
            bool lMatch = isMatch(lRegValueData, aVal.lDataType, lSearchParam);

            if (lMatch)
            {
                show(hkey, lHkeyPath, lCurrentSubKey, lRegValueData, false, true, false);
                lMatchTotal++;
            }

        }
        else
        {
            show(hkey, lHkeyPath, lCurrentSubKey, lRegValueData, false, true, false);

        }

        //Create a space after last data value
        if (lValueList.size() == 0 && !lSearchRecursive)
        {
            std::cout << "\n";
        }

    }

    // Remove visted Sub-Key from deque 
    lCurrentSubKey = lSubKeyList.front();
    lSubKeyList.pop_front();

    if (lSearchRecursive && lCurrentSubKey != L"End")
    {
        //Create a space after the first key.
        std::cout << "\n";

        // If the parent key contains sub-keys, add them to lSubKeyList, 
        // in the order they were retrieved from RegEnumEx.
        std::deque<std::wstring> lTemp;
        lResult = getSubKeyList(hkey, lHkeyPath, lCurrentSubKey, lTemp);

        while (lTemp.size())
        {
            lSubKeyList.push_front(lTemp.back());
            lTemp.pop_back();
        }

        // A non-error. Error: "Invalid Handle"
        // This error code just states that the current key being accessed 
        // does not contain any sub-keys.
        if (lResult == 6) lResult = 0;

        if (lResult != ERROR_SUCCESS)
        {
            error(lResult);
            return false;
        }

        // Get the current keys value names
        lResult = getValueNameList(hkey, lHkeyPath, lCurrentSubKey, lValueList);

        // Ignore key values that cannot be accessed. Error "Access Denied" 
        // Keys cannot be accessed in regedit (admin), so this is a UAC issue.
        if (lResult == 5) lResult = 0;

        if (lResult != ERROR_SUCCESS)
        {
            error(lResult);
            return false;
        }
    }
}

反汇编代码(std :: wcout << fPath.c_str())

        std::wcout << fPath.c_str();
00007FF67E5759E3  lea         rdx,[rbp]  
00007FF67E5759E7  cmp         qword ptr [rbp+18h],8  
00007FF67E5759EC  cmovae      rdx,qword ptr [rbp]  
00007FF67E5759F1  mov         rcx,qword ptr [__imp_std::wcout (07FF67E57D140h)]  
00007FF67E5759F8  call        std::operator<<<wchar_t,std::char_traits<wchar_t> > (07FF67E577CE0h)  
00007FF67E5759FD  nop  
    }
00007FF67E5759FE  mov         rax,qword ptr [rbp+18h]  
00007FF67E575A02  cmp         rax,8  
00007FF67E575A06  jb          show+4B8h (07FF67E575A68h)  
00007FF67E575A08  inc         rax  
00007FF67E575A0B  mov         rcx,qword ptr [rbp]  
00007FF67E575A0F  cmp         rax,r13  
00007FF67E575A12  jbe         show+46Bh (07FF67E575A1Bh)  
00007FF67E575A14  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575A1A  int         3  
00007FF67E575A1B  add         rax,rax  
00007FF67E575A1E  cmp         rax,1000h  
00007FF67E575A24  jb          show+4B3h (07FF67E575A63h)  
00007FF67E575A26  test        byte ptr [rbp],1Fh  
00007FF67E575A2A  je          show+483h (07FF67E575A33h)  
00007FF67E575A2C  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575A32  int         3  
00007FF67E575A33  mov         rax,qword ptr [rcx-8]  
00007FF67E575A37  cmp         rax,rcx  
00007FF67E575A3A  jb          show+493h (07FF67E575A43h)  
00007FF67E575A3C  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575A42  int         3  
00007FF67E575A43  sub         rcx,rax  
00007FF67E575A46  cmp         rcx,8  
00007FF67E575A4A  jae         show+4A3h (07FF67E575A53h)  
00007FF67E575A4C  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575A52  int         3  
00007FF67E575A53  cmp         rcx,27h  
00007FF67E575A57  jbe         show+4B0h (07FF67E575A60h)  
00007FF67E575A59  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575A5F  int         3  
00007FF67E575A60  mov         rcx,rax  
00007FF67E575A63  call        operator delete (07FF67E57B430h)  
00007FF67E575A68  mov         qword ptr [rbp+18h],7  
00007FF67E575A70  mov         qword ptr [rbp+10h],r12  
00007FF67E575A74  mov         word ptr [rbp],r12w  
00007FF67E575A79  mov         rax,qword ptr [rbp-28h]  
00007FF67E575A7D  cmp         rax,8  
00007FF67E575A81  jb          show+533h (07FF67E575AE3h)  
00007FF67E575A83  inc         rax  
00007FF67E575A86  mov         rcx,qword ptr [rbp-40h]  
00007FF67E575A8A  cmp         rax,r13  
00007FF67E575A8D  jbe         show+4E6h (07FF67E575A96h)  
00007FF67E575A8F  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575A95  int         3  
00007FF67E575A96  add         rax,rax  
00007FF67E575A99  cmp         rax,1000h  
00007FF67E575A9F  jb          show+52Eh (07FF67E575ADEh)  
00007FF67E575AA1  test        byte ptr [rbp-40h],1Fh  
00007FF67E575AA5  je          show+4FEh (07FF67E575AAEh)  
00007FF67E575AA7  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575AAD  int         3  
00007FF67E575AAE  mov         rax,qword ptr [rcx-8]  
00007FF67E575AB2  cmp         rax,rcx  
00007FF67E575AB5  jb          show+50Eh (07FF67E575ABEh)  
00007FF67E575AB7  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575ABD  int         3  
00007FF67E575ABE  sub         rcx,rax  
00007FF67E575AC1  cmp         rcx,8  
00007FF67E575AC5  jae         show+51Eh (07FF67E575ACEh)  
00007FF67E575AC7  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
    }
00007FF67E575ACD  int         3  
00007FF67E575ACE  cmp         rcx,27h  
00007FF67E575AD2  jbe         show+52Bh (07FF67E575ADBh)  
00007FF67E575AD4  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575ADA  int         3  
00007FF67E575ADB  mov         rcx,rax  
00007FF67E575ADE  call        operator delete (07FF67E57B430h)  
00007FF67E575AE3  mov         qword ptr [rbp-28h],7  
00007FF67E575AEB  mov         qword ptr [rbp-30h],r12  
00007FF67E575AEF  mov         word ptr [rbp-40h],r12w  
00007FF67E575AF4  mov         rax,qword ptr [rbp-48h]  
00007FF67E575AF8  cmp         rax,8  
00007FF67E575AFC  jb          show+5AEh (07FF67E575B5Eh)  
00007FF67E575AFE  inc         rax  
00007FF67E575B01  mov         rcx,qword ptr [rbp-60h]  
00007FF67E575B05  cmp         rax,r13  
00007FF67E575B08  jbe         show+561h (07FF67E575B11h)  
00007FF67E575B0A  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575B10  int         3  
00007FF67E575B11  add         rax,rax  
00007FF67E575B14  cmp         rax,1000h  
00007FF67E575B1A  jb          show+5A9h (07FF67E575B59h)  
00007FF67E575B1C  test        byte ptr [rbp-60h],1Fh  
00007FF67E575B20  je          show+579h (07FF67E575B29h)  
00007FF67E575B22  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575B28  int         3  
00007FF67E575B29  mov         rax,qword ptr [rcx-8]  
00007FF67E575B2D  cmp         rax,rcx  
00007FF67E575B30  jb          show+589h (07FF67E575B39h)  
00007FF67E575B32  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575B38  int         3  
00007FF67E575B39  sub         rcx,rax  
00007FF67E575B3C  cmp         rcx,8  
00007FF67E575B40  jae         show+599h (07FF67E575B49h)  
00007FF67E575B42  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575B48  int         3  
00007FF67E575B49  cmp         rcx,27h  
00007FF67E575B4D  jbe         show+5A6h (07FF67E575B56h)  
00007FF67E575B4F  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575B55  int         3  
00007FF67E575B56  mov         rcx,rax  
00007FF67E575B59  call        operator delete (07FF67E57B430h)  
00007FF67E575B5E  mov         qword ptr [rbp-48h],7  
00007FF67E575B66  mov         qword ptr [rbp-50h],r12  
00007FF67E575B6A  mov         word ptr [rbp-60h],r12w  
00007FF67E575B6F  mov         rax,qword ptr [rbp-8]  
00007FF67E575B73  cmp         rax,8  
00007FF67E575B77  jb          show+629h (07FF67E575BD9h)  
00007FF67E575B79  inc         rax  
00007FF67E575B7C  mov         rcx,qword ptr [rbp-20h]  
00007FF67E575B80  cmp         rax,r13  
00007FF67E575B83  jbe         show+5DCh (07FF67E575B8Ch)  
00007FF67E575B85  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575B8B  int         3  
00007FF67E575B8C  add         rax,rax  
00007FF67E575B8F  cmp         rax,1000h  
00007FF67E575B95  jb          show+624h (07FF67E575BD4h)  
00007FF67E575B97  test        byte ptr [rbp-20h],1Fh  
00007FF67E575B9B  je          show+5F4h (07FF67E575BA4h)  
00007FF67E575B9D  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575BA3  int         3  
00007FF67E575BA4  mov         rax,qword ptr [rcx-8]  
00007FF67E575BA8  cmp         rax,rcx  
00007FF67E575BAB  jb          show+604h (07FF67E575BB4h)  
00007FF67E575BAD  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575BB3  int         3  
00007FF67E575BB4  sub         rcx,rax  
00007FF67E575BB7  cmp         rcx,8  
00007FF67E575BBB  jae         show+614h (07FF67E575BC4h)  
00007FF67E575BBD  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575BC3  int         3  
00007FF67E575BC4  cmp         rcx,27h  
00007FF67E575BC8  jbe         show+621h (07FF67E575BD1h)  
00007FF67E575BCA  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF67E57D318h)]  
00007FF67E575BD0  int         3  
00007FF67E575BD1  mov         rcx,rax  
00007FF67E575BD4  call        operator delete (07FF67E57B430h)  

2 个答案:

答案 0 :(得分:0)

输出到控制台窗口的速度很慢,因为要进行大量的滚动操作(在文本缓冲区和屏幕上)。您可以将程序输出重定向到文件,并且性能应类似于没有输出的版本。

但是,为了进一步减少运行所需的时间,您需要尽可能减少字符串的使用。与其使用一系列+字符串操作(带有3个临时字符串对象),而是创建一个空字符串,为整个构造的字符串保留足够的空间,然后使用+=添加单个组件。将其设置为静态变量以避免额外的内存分配,并且仅在需要更多空间时才调整其大小。

答案 1 :(得分:0)

我在回答我自己的问题

我发现用<!DOCTYPE HTML> <html> <head> <title></title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin=""/> <!-- Make sure you put this AFTER Leaflet's CSS --> <script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js" integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw==" crossorigin=""></script> </head> <body> <div id="mapid" style="width: 1366px; height: 720px;"></div> <script> var mymap = L.map('mapid').setView([-2.729070029832631,107.64713287353514], 13); L.tileLayer('https://api.mapbox.com/styles/v1/hadicns/cjji5fjq61nru2rmiheweks5d/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGFkaWNucyIsImEiOiJjampoem5kbWIycjYzM3FudjA2cDJhZmN6In0.cYnG3YB44jr4yitE_HFSgg', { attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>', maxZoom: 18, id: 'mapbox.streets' }).addTo(mymap); function onMapClick(e) { popup .setLatLng(e.latlng) .setContent("You clicked the map at " + e.latlng.toString()) .openOn(mymap); } function onEachFeature(feature, layer) { // does this feature have a property named popupContent? if (feature.properties && feature.properties.popupContent) { layer.bindPopup(feature.properties.popupContent); } } var geojsonFeature = {"type":"FeatureCollection", "features":[ {"type":"Feature", "properties":{"siteid":"TJN012", "sitename":"TJN012MG1_TSEL_TanjungPandan3", "popupContent":"siteid: TJN012<br>sitename: TJN012MG1_TSEL_TanjungPandan3", }, "geometry":{"type":"Point", "coordinates":[107.63576,-2.72322]}, "id": 3126}, {"type":"Feature", "properties":{"siteid":"TJN002", "sitename":"TJN002MD1_TSEL_TanjungPandanII", "popupContent":"siteid: TJN002<br>sitename: TJN002MD1_TSEL_TanjungPandanII" }, "geometry":{"type":"Point", "coordinates":[107.65699,-2.7366]}, "id": 3127 }]}; L.geoJSON(geojsonFeature, { style: function (feature) { return feature.properties && feature.properties.style; }, onEachFeature: onEachFeature, pointToLayer: function (feature, latlng) { var colors = { 3126: "#000", 3127: "#001" }; return new L.circleMarker(latlng, { radius: 8, fillColor: colors[feature.properties.id], color: colors[feature.properties.id], weight: 1, opacity: 1, fillOpacity: 0.8 }); } }).addTo(mymap); L.geoJSON(geojsonFeature).addTo(mymap); L.geoJSON(geojsonFeature, { onEachFeature: onEachFeature }).addTo(mymap); </script> </body> </html>替换std::wcout << fPath.c_str();可以将控制台输出时间减少到3.45分钟以下。

但是,除了查看汇编代码时它执行的调用次数少于cout之外,我不太确定它执行得如此出色的原因。但是这个原因有点挑剔。

使用Performance Profiler结果,使用fwprintf,CPU(ms)类别(CPU执行代码所花费的时间)在50ms以下,而wcout在200ms以上。

我相信fwprintf在将内容显示到控制台之前会输出fPath内容的缓冲,而wcout似乎没有这样做。

我发现了一些堆栈溢出资源,这些资源使我对问题有所了解:

  1. 'printf' vs. 'cout' in C++
  2. What is it with printf() sending output to buffer?