在SpringREST控制器中执行的方法比在纯java项目中执行的要慢得多

在SpringREST控制器中执行的方法比在纯java项目中执行的要慢得多,java,spring,spring-boot,Java,Spring,Spring Boot,背景: 我正在开发一个SpringWeb应用程序,它为用户提供了一个优化算法。当在纯java项目中执行时,我的算法的性能是可以接受的。然而,在spring项目中通过rest控制器调用它会导致巨大的性能差距,我想理解这一点 测试/观察: 当然,所有测试都在同一硬件上执行。优化算法独立于spring,即它接收一些基本java对象作为输入并返回结果。正如您在下表中所看到的,在spring内部执行我的算法至少需要两倍的时间,即保持5次迭代和100次迭代(即开始时没有恒定的开销) 迭代[编号] 纯Java

背景: 我正在开发一个SpringWeb应用程序,它为用户提供了一个优化算法。当在纯java项目中执行时,我的算法的性能是可以接受的。然而,在spring项目中通过rest控制器调用它会导致巨大的性能差距,我想理解这一点

测试/观察: 当然,所有测试都在同一硬件上执行。优化算法独立于spring,即它接收一些基本java对象作为输入并返回结果。正如您在下表中所看到的,在spring内部执行我的算法至少需要两倍的时间,即保持5次迭代和100次迭代(即开始时没有恒定的开销)

迭代[编号] 纯Java[ms] 弹簧[ms] 5. ~200 ~ 400 100 ~1400 3500 - 5000
如果不知道你测量的确切方式,这些数字可能意味着完全为零(因为这与它们是什么无关)

如果您只是测量了
5
100
执行情况,那么您只测量了这些方法的“冷启动”,并且Spring明显较慢的事实是很有可能的;如果你知道引擎盖下弹簧是如何工作的。Spring将为所有rest控制器方法创建代理,这些方法也将放在引擎盖下的一个
tomcat
。。。为了简化我的意思,在
@RestController
中抛出一个
异常
,然后看看stacktrace——我想你会惊讶于它的深度


好消息是,一旦您对这些rest方法进行了多次调用,
JVM
将优化很多东西,并且调用将比您最初进行的调用快得多。尽管如此,与通过spring控制器调用普通方法相比,您永远无法击败它。

您在哪里测量了这些时间?在这两个例子中,你到底是如何调用你的算法的?代码中可能存在哪些差异?如果没有任何示例,就不可能正确回答(现在的任何回答都会对原因进行高度推测)。如果您通过在循环中调用算法来执行“纯Java代码”场景,则很可能是您构建代码的方式使jvm优化了方法调用。为了理解我的意思,请看@dunni,crizzis,Eugene:我刚刚更新了我的描述,解释了我是如何衡量这一点的。因此,我不是在循环中调用我的算法,该算法只触发一次并执行多次迭代。即使在您更新之后,我提供的答案仍然有效。@Eugene,如果我理解正确,Spring会为其余控制器创建代理。因此,当调用
@RestController
时,当然会有一些开销。但是,在触发
optimize()
时,应该不再涉及任何代理,对吗?这应该是我创建的java代码,对吗?那么,性能差距从何而来?