- 背景:**我正在开发一个为用户提供优化算法的spring web应用程序。当在纯java项目中执行时,我的算法的性能是可以接受的。但是,在spring项目中通过rest控制器调用它会导致巨大的性能差距,我想了解这一点。
- 测试/观察:**当然,所有的测试都在相同的硬件上执行。优化算法独立于spring,即它接收一些基本的java对象作为输入并返回结果。正如你在下表中所看到的,在spring中执行我的算法至少需要两倍的时间,分别为5次迭代和100次迭代(即开始时没有恒定的开销)。
| 迭代次数[编号]|纯Java [ms]|Spring[ms]|
| - ------|- ------|- ------|
| 五个|约200人|约400人|
| 一百|约1400年|3500至5000年|
我完全理解Web应用程序会给我的机器带来一些开销(Spring,Angular 等)。然而,您真的会期望如此巨大的性能影响吗?本质上,这只是一个很小的测试数据集,真实世界的数据集将会更具挑战性。
为了更详细地解释我是如何衡量这一点的:
- 我有一个
Optimization.class
,它包含一个public static Result optimize(Data data){}
。Data.class
是一个POJO,没有任何对Spring实体的引用。 optimize()
是一个有5或100次迭代的进化算法。上面给出的时间只在optimize()
内部测量,但在使用System.currentTimeInMillis()
的迭代循环周围。因此,我的方法只被触发一次,但执行不同的迭代次数,我只测量我的算法中这些迭代需要多长时间。Pure Java
意味着我创建了一个准备Data.class
并调用optimize()
的public static void main(String[] args)
。Spring
意味着我创建了一个准备Data.class
并调用optimize()
的rest控制器。- 主要问题:**如果您能帮助我更详细地了解这一问题,我将不胜感激。目前我正在思考以下问题:
- 哪些因素会影响Spring支架控制器内部执行的方法的性能?
- 我可以配置spring如何使用给定的硬件吗?
- 是否存在从客户端访问算法的任何替代方案,即,休息控制器的某种替代方案?
- 以某种异步方式执行我的算法并在稍后再次调用服务器以接收结果是否有帮助?
2条答案
按热度按时间yyyllmsg1#
如果不知道你测量的确切方式,这些数字可能意味着零(因为它们是什么是无关紧要的)。
如果您只是简单地测量
5
和100
的执行,那么您只测量了这些方法的“冷启动”,Spring明显更慢的事实是可以预料的;Spring会为你所有的rest控制器方法创建代理,它也会在tomcat
下运行......为了简化我的意思,在你的@RestController
中添加一个Exception
,然后查看堆栈跟踪--我想你会对它的深度感到惊讶。好消息是,一旦你调用了 * 许多 * rest方法,
JVM
将会优化很多东西,调用也会比你最初的调用快很多,但是,你永远无法击败普通的方法调用和通过spring控制器调用它。cbjzeqam2#
如果你使用IntelliJ,你需要禁用启动优化(这是运行配置中的spring特定选项)默认情况下,IntelliJ会为spring应用添加
-XX:TieredStopAtLevel=1
标志,这实质上阻止了c2编译,从而显著降低了计算量大的任务的速度。来源:https://youtrack.jetbrains.com/issue/IDEA-297872