我试图用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)
答案 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 © <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似乎没有这样做。
我发现了一些堆栈溢出资源,这些资源使我对问题有所了解: