Question

Je mène une recherche de fichiers et il y a la liste des exceptions pour les répertoires, le problème est au-dessous du code itère récursive dans tous les fichiers sur les disques durs. Il fonctionne, mais il est lent. , Je dois donc aider à optimiser ses performances. Merci à l'avance.

CFileFind finder;

    // build a string with wildcards
    CString strWildcard(directory);
    strWildcard += _T("\\*.*");

    // start working for files
    BOOL bWorking = finder.FindFile(strWildcard);

    while (bWorking)
    {
        bWorking = finder.FindNextFile();

        if (finder.IsDots())
            continue;

        // if it's a directory, recursively search it

        if (finder.IsDirectory())
        {
            CString str = finder.GetFilePath();
            if(NULL == m_searchExceptions.Find(str)){
                _recursiveSearch(str);
            }
            else{
                continue;
            }
        }
        //basic comparison, can be replaced by strategy pattern if complicated comparsion required (e.g. REGEX)
        if(0 == finder.GetFileName().CompareNoCase(m_searchPattern)){
            if(m_currentSearchResults.Find(finder.GetFilePath()) == NULL){
                m_currentSearchResults.AddHead(finder.GetFilePath());       
            }
        }
    }
Était-ce utile?

La solution

Je ne pense pas que vous allez être en mesure d'optimiser les performances ici. Vous allez dépenser 80 +% de votre temps à l'intérieur FindFirstFile et FindNextFile ici (windows appels API), peu importe ce que vous faites en termes d'optimisation de votre côté.

j'ai posé une question similaire déjà et ont encore pour obtenir une réponse.

Autres conseils

On dirait que votre m_currentSearchResults est une liste, et chaque fois que vous trouvez un nom de fichier que vous regardez vers le haut si elle est déjà dans la liste. Dans le cas où vous avez beaucoup de fichiers trouvés (centaines par exemple), cela peut devenir un goulot d'étranglement car il a la complexité de O(N^2). Si tel est le cas, envisagez d'utiliser un CMap au lieu car il vous donne O(log N) recherche (un ensemble serait encore plus approprié qu'une carte, mais vous n'avez pas dans MFC mais vous pouvez également utiliser le std::set de la bibliothèque standard à la place).

Comment lent? Avez-vous de profil lui? Si vous récursive recherche de fichiers sur votre disque dur, il est vous êtes d'E / S très probablement lié et il n'y a rien que vous pouvez faire à court d'obtenir du matériel de stockage plus rapide (comme l'état solide).

Vous faites une recherche générale pour un fichier. Il y a un million de produits là-bas qui font bien, et ils ont tous l'indexation de l'utilisation comme une optimisation. Le maillon faible est ici certainement votre disque, pas votre code. En comparant 1.000.000 chaînes ne prendra pas de temps par rapport au temps qu'il faut pour énumérer 1.000.000 fichiers sur le disque.

Il y a deux questions fondamentales sur la performance ici: l'accès du disque dur et directory traversal. Les deux vous peut être en mesure d'optimiser le.

Optimisation du disque dur

Un disque dur au repos tend à rester au repos. Un cylindre de filature aime garder la filature. Ainsi dit, les goulots d'étranglement dans l'accès aux disques durs commencent vers le haut, le temps de recherche et le temps de lecture. La réduction de la quantité d'accès et d'augmenter la quantité de données par lecture augmentera vos performances.

accès à la mémoire est plus rapide que l'accès du disque dur. Donc transporter de gros morceaux de données en mémoire, puis recherchez la mémoire.

Répertoire Optimizing Recherche.

Imaginez, si vous voulez, un arbre de « pages ». Chaque nœud de l'arbre est un répertoire de zéro ou plusieurs répertoires ou fichiers. Malheureusement, dans la plupart des systèmes d'exploitation à cette structure de données ne sont pas optimisées pour la recherche efficace.

La situation idéale est à distance dans tous les répertoires concernés en mémoire puis la recherche (en mémoire). Une fois l'emplacement du fichier est connu, l'accès aléatoire au fichier est relativement rapide. Le problème est de réduire le temps de recherche en ne lisant que les répertoires concernés; à-dire réduire le nombre de répertoire non pertinent lectures.

La plupart des applications qui effectuent la recherche de fichiers sur un disque dur lire le lecteur et créer leur propre structure de données optimisée (s). Cela peut ne pas être optimale pour d'énormes disques durs avec des quantités enormouse des fichiers ou des cas de quelques recherches de fichiers.

Si vous pouvez, dire le système d'exploitation de garder autant de répertoires dans la mémoire que possible.

Amélioration de la performance: la réduction d'autres applications

.

Pour certaines applications, le temps de la performance perçue dépend d'autres applications en cours d'exécution en même temps. Exécution d'un compilateur et une recherche sur Internet en même temps que ralentira la plupart des autres applications. Donc, essayez d'éliminer d'autres applications qui ne sont pas nécessaires de fonctionner en même temps que le vôtre. En outre, l'investissement lainage la priorité de votre application.

+1 pour le profil d'abord pour être sûr. En outre, cela semble être un problème qui pourrait également être résolu en utilisant bibliothèque parallèle de tâches - lancer une tâche que vous voyez chaque répertoire, et utiliser tous les cœurs sur votre CPU -

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top