libgit: самый быстрый способ получения файлов в коммите

Мне нужно перебирать коммиты репозитория и извлекать затронутые файлы для каждого коммита. Это мое огромный узкое место производительности в настоящее время.

У меня есть оболочка C ++ вокруг функций libgit, но этот фрагмент должен быть достаточно понятным.

std::vector<std::string> Commit::getAffectedFiles() const {
git_tree* tree = nullptr;
git_tree* tree2 = nullptr;
int error = git_commit_tree(&tree, get());
throw_on_error(error);

try {
error = git_commit_tree(&tree2, parent(0).get());
} catch (GitException e) {
tree2 = nullptr; // probably initial commit
}
git_diff* diff = nullptr;
git_diff_tree_to_tree(&diff, getRepo(), tree2, tree, 0);

std::vector<std::string> ret;
git_diff_foreach(diff,
[](const git_diff_delta* entry, float progress, void* payload) {
std::string str = entry->old_file.path;
((std::vector<std::string>*)payload)->push_back(str);
return 0;
}, nullptr, nullptr, nullptr, &ret);
git_tree_free(tree);
git_tree_free(tree2);
git_diff_free(diff);
return ret;
}

Я могу только надеяться, что я делаю что-то в корне неправильно здесь.


Например

git log --stat > /dev/null

это намного быстрее, и предоставляет ту же информацию.


перф сообщает о наибольшем использовании git__strncmp, git_buf_rfind_next а также git_tree__parse с целью.


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

1

Решение

Это эквивалентно тому, что делает git внутри, хотя в самом git было больше людей, которые смотрели на это с точки зрения производительности, а libgit2 не вкладывала в это почти столько же.

Тем не менее, несколько патчей [0] недавно были объединены с libgit2 master ветка, которая может сократить до 40% времени разбора дерева. Я бы порекомендовал попробовать это и посмотреть, какие цифры вы получите (патчи должны легко переноситься на более ранние версии).

Также учтите, что ваша версия git, скорее всего, скомпилирована в режиме выпуска, а libgit2 по умолчанию собирается в режиме отладки, поэтому, если вы не активировали режим выпуска, запустите cmake с -DCMAKE_BUILD_TYPE=Release, Это также значительно ускоряет эти операции анализа.

[0] Специально PR 3508 и совершает 0174f2 а также fc4364

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]