c ++循环通过注册表递归缓慢

时间:2011-09-19 14:03:13

标签: c++ python registry

我的代码有一个恼人的问题,可能是我做错了因为我的Python 实施要快得多!

C ++实现问题:

  1. 迭代“HKEY_CLASSES_ROOT”会占用大量内存,我认为这是因为c ++实现使用了大量变量。的 固定
  2. 它也慢,比python植入代码慢得多 固定
  3. 尝试迭代HKEY_CLASSES_ROOT时代码更慢 已修复
  4. 新问题:

    1. 感谢 Nam Nguyen 我理解导致代码泄漏的原因,并直接影响执行时间,下面的代码是固定代码。为什么c ++实现的运行速度与我的python实现一样快?
    2. C ++实现:

      #include <iostream>
      #include <windows.h>
      #include <stdio.h>
      #include <tchar.h>
      #include <string>
      
      using namespace std;
      
      #define MAX_KEY_LENGTH 255
      
      int RecurseOpenRegEx(HKEY hkey, string subKey = "",string search = "nothing", DWORD sum = 0)
      {
         TCHAR csubKey[MAX_KEY_LENGTH];
         DWORD nSubKeys = 0;
         DWORD pathLength = MAX_PATH;
         TCHAR storeKeyName[MAX_KEY_LENGTH];
         DWORD keyLength;
         HKEY hKey = hkey; //somehow i need to reassign HKEY, otherwise it won't pass it with the function, this is bigger than me tough...
      
         const char * ccsearch = search.c_str();
         const char * ccsubKey;
      
      
         if (subKey != "")
         {
             ccsubKey = subKey.c_str();
             copy(subKey.begin(), subKey.end(),csubKey); //convert string to TCHAR
         }
      
         if (RegOpenKeyEx(hkey, ccsubKey, 0, KEY_READ, &hkey) == ERROR_SUCCESS)
         {
             if (RegQueryInfoKey(hkey, csubKey, &pathLength, NULL,&nSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
             {
                 sum += nSubKeys;
                 for (DWORD subKeyIndex = 0; subKeyIndex < nSubKeys; subKeyIndex++)
                 {
                     keyLength = MAX_KEY_LENGTH;
                     if (RegEnumKeyEx(hkey, subKeyIndex, storeKeyName, &keyLength, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
                     {
                         string sKeyName = storeKeyName; //Convert TCHAR to string explicitly
      
      
                         if (subKey != "")
                         {
                             sKeyName = subKey + "\\" + sKeyName;
                         }
                         sum += RecurseOpenRegEx(hKey, sKeyName);
                     }
                 }
             }
         }
         RegCloseKey(hkey); //Now closing the right key
         return sum;
      }
      
      int main()
      {
         cout << "sum of all keys: " << RecurseOpenRegEx(HKEY_LOCAL_MACHINE);
         return 0;
      }
      

      Python实现:

      import winreg
      
      def recurseRegistrySearch(key, keySearch = "",subkey = "", subkeypath = "", x = 0):
          key = winreg.OpenKey(key, subkey, 0)
          y = winreg.QueryInfoKey(key)[0]
          x += y
          for items in range(x):
              try:
                  subkey = winreg.EnumKey(key, items)
                  if ((keySearch.lower() in subkey.lower()) and (keySearch != "")):
                      print(subkeypath + "\\" + subkey)
                  x += recurseRegistrySearch(key, keySearch, subkey, subkeypath = subkeypath + "\\" + subkey)
              except WindowsError:
                  pass
          return x
      
      print("sum of all keys: {0}".format(recurseRegistrySearch(winreg.HKEY_CLASSES_ROOT)))
      

2 个答案:

答案 0 :(得分:4)

您的代码中存在资源泄漏。您打开hkey但关闭hKey(请注意kK的区别。)

在旁注中,您将打开的注册表项存储到hkey本身。并且恰好hkey是传入参数,在RecurseOpenRegEx的所有调用中共享。这就是为什么“不知何故我需要重新分配HKEY”。

基本上,我现在可以建议您立即清理代码。当您的代码难以阅读时,很难发现这些错误。完成后,我相信您会发现调试/跟踪更容易。

答案 1 :(得分:1)

可能是你大量使用字符串变量,这涉及很多动态内存分配。

尝试接受参数作为LPCTSTR。使用那些LPCTSTR在函数内部分配字符串变量,并使用str.c_str()传递参数。