【问题标题】:How to put a threshold on "runtime complexity" of a Maven module?如何为 Maven 模块的“运行时复杂性”设置阈值?
【发布时间】:2022-01-21 19:42:58
【问题描述】:

我正在寻找一个 Maven 插件,它可以测量模块中所有单元测试的运行时复杂度,如果它高于阈值,则构建失败。我需要这个来防止意外增加复杂性,这不会破坏功能但会使代码变慢。存在吗?

【问题讨论】:

  • 如何定义运行时复杂度?你关心什么代码:你的单元测试或生产代码。如果出现性能回归,集成测试失败是很常见的。
  • @tgdavies 如何定义“运行时复杂性”取决于插件,我已准备好依赖他们的指标。当然,它将同时测试测试和生产代码。您将如何编写您提到的这样一个集成测试?

标签: java maven maven-plugin


【解决方案1】:

复杂性是关于性能指标的变化随着特定参数或参数的增加。运行一套单元测试的时间没有一个有意义的复杂性度量......因为:

  • (通常)没有一组参数可以针对任何单独的测试进行更改,并且
  • 测试套件的整体性能是各个测试的总和,这些测试通常会做完全不同的事情。

方法具有复杂性。但是您需要深入了解哪些方法很重要,它们的用途,以及复杂性度量的参数应该是什么,以便生成一些有意义的“经验”复杂性近似值他们。我认为任何人尝试实现 Maven 或 IDE 插件来做这种事情的可能性不大。或者,如果他们曾经这样做过,那将是可靠的。


我的建议是:

  • 找出对应用程序性能至关重要的方法和参数。

  • 编写一些性能测试来运行一系列参数的方法。

  • 编写一些“线束”代码来运行测试、捕获度量并将它们与您所针对的复杂性类别的“预测”进行比较……针对每个度量。

  • 将这些测试集成到您的测试体系中。

但要小心编写 Java 微基准测试的陷阱;见How do I write a correct micro-benchmark in Java?


实际上...我的更好建议是根本不要尝试衡量复杂性。相反,只需为您的应用程序创建一些常规基准测试,并确定一些性能阈值以引发您的注意。毕竟,您的真正目标应该是性能,而不是复杂性。

【讨论】:

  • 我想把这个性能/复杂性检查放到构建管道中,防止程序员增加复杂性。就像我们运行所有单元测试和样式检查器一样。
  • 您可以将基准放入管道中,如果您的性能阈值被违反,则让它们无法构建。但是衡量>复杂性
  • 如果我按照您的建议进行操作,我的构建将取决于执行它的环境。在速度更快的计算机上,它可能不会失败。另一方面,测量复杂性(测试执行的字节码指令的数量)将是一种更安全的方法。
  • 啊......所以你想测量执行的字节码。 (这也不复杂,我不知道你是怎么做到的!)但是你肯定会一直在相同的硬件上运行构建管道......在你的 CI 服务器上。
  • 嗯,构建管道首先由程序员在笔记本电脑上运行,然后在 CI 服务器上运行 :) 所以,至少有两个地方的数字应该匹配。
【解决方案2】:

下面有checkstyleMetrics 表示源代码的复杂性。 Cyclomatic Complexity 是最适合您要求的工具。

  • BooleanExpressionComplexity - 限制表达式中布尔运算符(&&||&|^)的数量。
  • ClassDataAbstractionCoupling - 测量给定类或记录中其他类的实例化数量。
  • ClassFanOutComplexity - 检查给定类/记录/接口/枚举/注释所依赖的其他类型的数量。
  • CyclomaticComplexity - 根据指定限制检查圈复杂度。它是通过源的最小可能路径数量的度量,因此是所需测试的数量。
  • JavaNCSS - 通过计算非注释源语句 (NCSS) 来确定方法、类和文件的复杂性。
  • NPathComplexity - 根据指定限制检查 NPATH 复杂性。 NPATH 指标通过函数(方法)计算可能的执行路径数。

我们可以为他们启用 maven pom.xml 文件

【讨论】:

  • 我认为 OP 是在询问 Big-O 复杂性;即“不幸”的代码更改使代码运行缓慢的那种。
  • @StephenC - 是的,我同意。它要求测试用例运行时复杂性,并与 maven - 1 一起使用,我还没有找到这样的工具,Cyclomatic Complexity 是最接近 maven 插件样式的工具,但不是@yegor256 想要的确切工具 2,另一种方法在运行测试用例时进行 JVM 分析,无论是单元测试还是集成测试;这是我们现在用来监控性能下降的方法;好吧,JVM 分析无法与 maven 集成,但不幸的是它是一个独立的工具
  • 代码的圈复杂度可能很低,同时它的运行时(也就是性能)很差。
猜你喜欢
  • 2014-11-02
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
  • 2021-05-14
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
相关资源
最近更新 更多