C ++ рекурсивно проходит через реестр медленно - PullRequest
0 голосов
/ 19 сентября 2011

Возникла досадная проблема с моим кодом, возможно, я что-то делаю не так, потому что моя реализация на Python намного быстрее!

Проблемы с реализацией на C ++:

  1. Для перебора "HKEY_CLASSES_ROOT" требуетсяЯ полагаю, что это связано с тем, что реализация c ++ использует много переменных. Исправлено
  2. Это также медленно, намного медленнее, чем имплантация кода на python Исправлено
  3. Код даже медленнее при попытке перебрать HKEY_CLASSES_ROOT Исправлено

Новые вопросы:

  1. Благодаря NamНгуен Я понял, что вызывает утечки в моем коде и напрямую влияет на время выполнения, код ниже является фиксированным.Почему реализация C ++ работает так же быстро, как и моя реализация Python?

Реализация 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 ]

4 голосов
/ 19 сентября 2011

В вашем коде есть утечка ресурсов. Вы открываете hkey, но закрываете hKey (обратите внимание на разницу в случае k и K).

Кстати, вы сохраняете открытый ключ реестра в самом hkey. И бывает, что hkey - это переданный параметр, общий для всех вызовов RecurseOpenRegEx. Вот почему «как-то мне нужно переназначить HKEY».

По сути, сейчас я могу посоветовать вам немедленно очистить ваш код. Подобные ошибки трудно обнаружить, когда ваш код слишком сложен для чтения. Я полагаю, что после этого вам будет легче отлаживать / отслеживать.

1 голос
/ 19 сентября 2011

Вероятно, вы интенсивно используете строковые переменные, что связано с большим количеством динамического выделения памяти.

Попробуйте принять параметры как строковые переменные LPCTSTR .assign внутри функции с этими LPCTSTR и передать параметры с помощью str.c_str ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...