java - 在 Spring Rest Controller 中执行的方法比在纯 java 项目中执行的方法要慢得多
问题描述
背景: 我正在开发一个为用户提供优化算法的 Spring Web 应用程序。在纯 java 项目中执行时,我的算法的性能是可以接受的。但是,通过 spring 项目中的休息控制器调用它会导致我想理解的巨大性能差距。
测试/观察: 当然,所有测试都在同一硬件上执行。优化算法独立于spring,即它接收一些基本的java对象作为输入并返回一个结果。正如您在下表中看到的,执行我的算法至少需要两倍的时间在 spring 内部,它可以保持 5 次迭代和 100 次迭代(即开始时没有恒定的开销)。
迭代次数 [No.] | 纯 Java [毫秒] | 弹簧 [毫秒] |
---|---|---|
5 | ~200 | ~ 400 |
100 | ~1400 | 3500 - 5000 |
我完全理解 Web 应用程序会导致我的机器上的一些开销(弹簧、角度等)。但是,您真的会期望如此巨大的性能影响吗?本质上,这只是一个小的测试数据集,现实世界的数据集将更具挑战性。
为了更详细地解释我是如何测量这个的:
- 我有一个
Optimization.class
包含一个public static Result optimize(Data data){}
.Data.class
是一个 POJO,没有任何对 spring 实体的引用。 optimize()
是具有 5 或 100 次迭代的进化算法。上面给出的时间仅在optimize()
迭代循环内部但使用System.currentTimeInMillis()
. 因此,我的方法只触发一次,但执行了不同次数的迭代,我只测量我的算法中这些迭代需要多长时间。Pure Java
意味着我创建了一个public static void main(String[] args)
准备Data.class
和调用optimize()
.Spring
意味着我创建了一个准备Data.class
和调用optimize()
.
主要问题: 我非常感谢任何有助于更详细地理解这个问题的帮助。目前我正在考虑以下问题:
- 哪些因素会影响在弹簧架控制器内执行的方法的性能?
- 我可以以某种方式配置spring如何使用给定的硬件吗?
- 是否有任何替代方法可以从客户端访问算法,即其他控制器的替代方法?
- 以某种异步方式执行我的算法并稍后再次调用服务器以接收结果是否有帮助?
解决方案
在不知道您测量的确切方式的情况下,这些数字可能意味着完全为零(因为它们与它们的含义无关)。
如果你只是测量5
和100
执行,你只测量了那些方法的“冷启动”,Spring 明显慢的事实是非常值得期待的;如果您知道 Spring 是如何在幕后工作的。Spring 将为您的所有休息控制器方法创建代理,这也将tomcat
在引擎盖下进行...为了简化我的意思,将一个Exception
放入您的@RestController
并查看堆栈跟踪 - 我认为您会对它的深度感到惊讶.
好消息是,一旦你对这些 rest 方法进行了多次JVM
调用,就会优化很多东西,并且调用会比你最初做的快得多。尽管如此,您将永远无法击败简单的方法调用与通过弹簧控制器调用它。
推荐阅读
- c++ - 如何在类中将向量初始化为一定长度?
- php - Laravel 5.6 迁移问题
- perl - CentOS 服务器上的 Perl setpriority 函数
- powershell - 在 PowerShell v2 中构建发布请求的问题
- java - 如何在 Java 中声明二维数组并实现它们(过程编程)
- php - 在 wordpress 中使用 sql 查询的结果进行表计算
- c# - 带有 LIST 对象和其他混合数据类型的 POST 方法的 FormUrlEncodedContent
- sql-server - SQL Pivot 数据到每个项目一行
- php - PHP API:两个环境中的相同代码,在同一台服务器上,不同的速度
- c++ - 寻找 VS 2010 库的 VisualStudio 2015 链接器