Как найти похожий фрагмент кода? - PullRequest
19 голосов
/ 02 апреля 2009

У кого-нибудь есть какой-нибудь инструмент или рекомендуемая практика, как найти кусок кода, который похож на какой-то другой код?

Часто я пишу функцию или фрагмент кода, и я помню, что уже писал что-то подобное раньше, и я хотел бы повторно использовать предыдущую реализацию, однако использование простого текстового поиска ничего не показывает, так как я не использовал переменную имена, которые были бы точно такими же.

Наличие похожих фрагментов кода приводит к ненужному дублированию кода, однако при большой кодовой базе невозможно сохранить весь код в памяти. Существуют ли какие-либо инструменты, которые могли бы выполнить некоторый анализ кода и отмеченных фрагментов или функций, которые «похожи» по функциональности?

Рассмотрим следующие примеры:

  float xDistance = 0, zDistance = 0;
  if (camPos.X()<xgMin) xDistance = xgMin-camPos.X();
  if (camPos.X()>xgMax) xDistance = camPos.X()-xgMax;
  if (camPos.Z()<zgMin) zDistance = zgMin-camPos.Z();
  if (camPos.Z()>zgMax) zDistance = camPos.Z()-zgMax;
  float dist = sqrt(xDistance*xDistance+zDistance*zDistance);

и

  float distX = 0, distZ = 0;
  if (cPos.X()<xgMin) distX = xgMin-cPos.X();
  if (cPos.X()>xgMax) distX = cPos.X()-xgMax;
  if (cPos.Z()<zgMin) distZ = zgMin-cPos.Z();
  if (cPos.Z()>zgMax) distZ = cPos.Z()-zgMax;
  float dist = sqrt(distX*distX +distZ*distZ);

Мне кажется, об этом уже спрашивали и отвечали несколько раз:

https://stackoverflow.com/questions/204177/what-tool-to-find-code-duplicates-in-c-projects

Как обнаружить дублирование кода во время разработки?

Я предлагаю закрыть здесь как дубликат.


На самом деле, я думаю, что это более общая проблема поиска, например: Как искать, если вопрос уже задавался в StackOverflow?

Ответы [ 3 ]

10 голосов
/ 02 апреля 2009

Вы можете использовать Simian . Это инструмент, который обнаруживает дублирующийся код в Java, C #, C ++, XML и многих других (даже простых текстовых файлах). Он даже прекрасно интегрируется в такой инструмент, как CruiseControl.

3 голосов
/ 23 августа 2009

Наш CloneDR находит дубликаты кода, как точные копии, так и ошибки, в больших исходных системах, параметризованные с помощью синтаксиса языка. Он поддерживает Java, C #, COBOL, C ++, PHP, Python и многие другие языки.

Он принимает ряд параметров для определения «Что такое клон?», В том числе: a) Порог подобия, управляющий тем, насколько похожи два блока кода быть объявленным клонами (обычно 95% - это хорошо) б) количество линий минимальный размер клона (3, как правило, хороший выбор) c) количество параметров (четкие изменения в тексте; 5, как правило, хороший выбор) С этими настройками он имеет тенденцию находить 10-15% избыточного кода виртуально все это обрабатывает.

Линейно-ориентированные инструменты обнаружения клонов, такие как Simian, не могут найти клонированный код, который был переформатирован, но CloneDR будет. Они могут сказать, что два блока кода совпадают, но они обычно не показывают вам точно, как они соответствуют или где различия; CloneDR будет. Они не предлагают, как абстрагировать клонированный код; CloneDR будет.

В силу более слабого соответствия алгоритмы, они имеют тенденцию производить больше ложных срабатываний; когда вы получите 5000 клонов через миллион строк количество ложных срабатываний имеет большое значение.

На основании вашего примера я бы ожидал, что он найдет эти два фрагмента (у вас нет ни того, ни другого) и обратите внимание, что они похожи, если абстрагировать имена переменных.

0 голосов
/ 16 декабря 2012

Вот лучшая коллекция по обнаружению клонов кода, которую я видел:

https://web.archive.org/web/20120502162147/http://students.cis.uab.edu/tairasr/clones/literature

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

...