如何找到类似的代码片段?

时间:2009-04-02 13:36:13

标签: language-agnostic search maintenance code-duplication

有没有人有一些工具或一些推荐的练习如何找到一段与其他代码相似的代码?

我经常写一个函数或一个代码片段,我记得我之前已经写过类似的东西了,我想重用以前的实现,但是使用纯文本搜索并没有透露任何东西,因为我没有使用变量名称将完全相同。

具有相似的代码片段会导致不必要的代码重复,但是如果代码库很大,则无法将所有代码保留在内存中。是否有任何工具可以对代码进行某些分析,并在功能方面标记片段或功能“相似”?

请考虑以下示例:

  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

How to detect code duplication during development?

我建议在此处复制。


实际上我认为这是一个更普遍的搜索问题,例如:如何在StackOverflow上询问问题时如何搜索?

3 个答案:

答案 0 :(得分:10)

您可以使用Simian。它是一个工具,可以检测Java,C#,C ++,XML等更复杂的代码(甚至是普通的txt文件)。它甚至可以很好地集成在像CruiseControl这样的工具中。

答案 1 :(得分:3)

我们的CloneDR在大型源系统中找到重复的代码,包括精确副本和接近未命中,由langauge语法参数化。它支持Java,C#,COBOL,C ++,PHP,Python和许多其他语言。

它接受许多参数来定义“什么是克隆?”,包括: a)相似的阈值,控制两个代码块的相似程度    被宣布为克隆(通常95%是好的) b)行数最小克隆大小(3往往是一个不错的选择) c)参数数量(文本的明显变化; 5往往是一个不错的选择) 通过这些设置,它可以真正找到10-15%的冗余代码 它处理的一切。

线性克隆检测工具如Simian找不到克隆代码 已经重新格式化,但CloneDR会。他们可能会说两个代码块匹配, 但他们通常不会准确地告诉你他们如何匹配或差异在哪里; CloneDR会。他们没有建议如何抽象克隆代码; CloneDR会。

由于匹配较弱 算法,它们往往产生更多的误报;当你报告了5000个克隆时 在一百万行中,误报的数量很重要。

根据你的例子,我希望它能找到这两个片段 (你没有指向任何一个)并注意到它们 如果你抽象掉变量名,它们就是相似的。

答案 2 :(得分:-1)

以下是我见过的代码克隆检测的最佳集合:

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

有许多节目,但它们似乎都不是最好的或最受欢迎的节目。您可以考虑什么对您最重要,并找到适合您的需求。