在Spring Rest Controller中执行的方法比纯Java项目中执行的方法慢得多

4
背景: 我正在开发一个Spring Web应用程序,为用户提供优化算法。当在纯Java项目中执行时,我的算法的性能是可接受的。然而,在Spring项目中通过Rest控制器调用它会导致巨大的性能差距,我希望理解其中的原因。
测试/观察: 当然,所有测试都在相同的硬件上执行。 优化算法独立于Spring,即它接收一些基本的Java对象作为输入并返回结果。正如您在下表中所看到的,执行我的算法需要至少两倍于Spring内部执行,在5次迭代和100次迭代中(即开始没有恒定的开销)。
迭代[次数] 纯Java[ms] Spring[ms]
5 ~200 ~400 100 ~1400 3500-5000
我完全理解Web应用程序会在我的机器上产生一些开销(Spring、Angular等)。 但是,您真的希望有如此巨大的性能影响吗? 实际上,这只是一个小的测试数据集,现实世界的数据集将更具挑战性。
为了更详细地解释我如何进行测量:
我有一个Optimization类,其中包含一个public static Result optimize(Data data){}。 Data类是POJO,没有任何参考Spring实体的内容。
optimize()是一种演化算法,具有5或100个迭代。上面给出的时间仅在optimize()内部测量,但围绕着迭代循环使用System.currentTimeInMillis()。 因此,我的方法只被触发一次,但对不同数量的迭代执行,并且我只测量这些迭代在我的算法中所需的时间。
纯Java表示我创建了一个public static void main(String[] args),准备Data类并调用optimize()。
Spring表示我创建了一个Rest控制器,准备Data类并调用optimize()。
主要问题: 我非常感谢任何帮助更好地理解这个问题。目前,我正在思考以下问题:
  • 什么因素会影响在Spring Rest Controller中执行方法的性能?
  • 我是否可以配置Spring如何使用给定的硬件?
  • 有没有其他替代方式可以从客户端访问算法,即一些替代Rest Controller的方式?
  • 将我的算法以某种异步方式执行并稍后再次调用服务器以接收结果是否有帮助?

3
你在哪里测量这些时间?你在两个例子中如何准确地调用算法?代码可能有什么不同之处?没有任何示例,就无法正确回答(目前任何答案都将高度推测原因)。 - dunni
如果您通过在循环中调用算法来执行“纯Java代码”场景,那么您构建代码的方式很可能会使jvm优化掉您的方法调用。要了解我的意思,请参见此文章 - crizzis
@dunni,crizzis,Eugene:我刚刚更新了我的描述以解释我如何进行测量。因此,我不是在循环中调用我的算法,而是只触发一次算法并执行多个迭代。 - chrisb89
@Eugene,如果我理解正确的话,Spring会为rest控制器创建代理。因此,当调用@RestController时,肯定会有一些开销。但是,当触发optimize()时,不应再涉及任何代理,对吗?这应该只是我创建的Java代码,对吗?那么性能差距从哪里来呢? - chrisb89
@chrisb89 我认为如果没有运行分析器,回答这个问题几乎是不可能的。正如答案中所说,你正在测量方法的“冷启动”,这种测量是不可预测的,并且受到许多因素的影响。 - Eugene
显示剩余2条评论
2个回答

1

如果不知道你是如何测量的,这些数字可能意味着零(即它们是无关紧要的)。

如果你只是测量了5100次执行,那么你只是测量了这些方法的“冷启动”,而且Spring要慢得多是非常预期的;如果你知道Spring在底层是如何工作的话。Spring会为所有的rest控制器方法创建代理,这些代理也会在底层的tomcat下运行...简单来说,只需在@RestController中抛出一个Exception并查看堆栈跟踪 - 你会惊讶于它的深度。

好消息是,一旦你有了很多调用这些rest方法的机会,JVM将优化很多事情,调用会比最初的调用快得多。但是,你永远无法击败直接调用普通方法与通过spring控制器调用它之间的差异。


1
如果您正在使用IntelliJ,则需要禁用启动优化(这是运行配置中的特定于Spring的选项)。默认情况下,IntelliJ为Spring应用程序添加标志 -XX:TieredStopAtLevel = 1 ,这实际上防止了c2编译,从而使计算密集型任务显着变慢。
来源:https://youtrack.jetbrains.com/issue/IDEA-297872

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接