当前位置: 首页 > 知识库问答 >
问题:

java性能优化 - 为什么Spring环境中for循环执行耗时比非Spring环境多?

蔚琦
2024-09-02

同样的for循环语句,在spring环境中执行和不在spring环境中执行,耗时不同。

@RestController
@RequestMapping("api/")
public class ApiV2Controller {

    @RequestMapping(value = "upload")
    public void upload() throws IOException {
        for (int i = 0; i < 10; i++) {
            long l = System.currentTimeMillis();
            encode();
            System.out.println("controller耗时:" + (System.currentTimeMillis() - l));
        }

    }

    public static void main(String[] args) throws IOException {
        for (int i = 0; i < 10; i++) {
            long l = System.currentTimeMillis();
            encode();
            System.out.println("main耗时:" + (System.currentTimeMillis() - l));
        }
    }

    private static void encode() throws IOException {
        File file = new File("C:\\Users\\admin\\Desktop\\demo.bin");
        byte[] fileBytes = Files.readAllBytes(file.toPath());
        int index = 0;
        byte[] key = "onekey;".getBytes(StandardCharsets.UTF_8);
        int keylen = key.length;
        int length = fileBytes.length;
        for (int i = 0; i < length; i++) {
            if (index >= keylen) {
                index = 0;
            }
            int diff = fileBytes[i] - key[index];
            if (diff < -128) {
                diff += 256;
            }
            fileBytes[i] = (byte) diff;
            index++;
        }
    }

代码的for循环是一个常用的用key加密文件的方法
在spring中执行耗时
controller耗时:399
controller耗时:368
controller耗时:367
controller耗时:366
controller耗时:368
controller耗时:367
controller耗时:367
controller耗时:367
controller耗时:367
controller耗时:367
使用普通的main方法耗时
main耗时:137
main耗时:118
main耗时:114
main耗时:114
main耗时:114
main耗时:116
main耗时:117
main耗时:118
main耗时:111
main耗时:113

spring中执行耗时会多2-3倍,文件大小为64Mb

很疑惑,不知道为什么会这样

求解答

共有1个答案

洪旻
2024-09-02

在Spring环境中,特别是当你通过Spring MVC的@RestController@RequestMapping处理HTTP请求时,相比直接在main方法中执行相同的逻辑,存在几个潜在的原因导致执行时间显著增加:

  1. Spring容器初始化:在Spring环境中,每次HTTP请求都会经历Spring容器的初始化、依赖注入等过程,尽管这些过程对于单个请求来说是微秒级别的,但在大量请求或复杂应用中可能会累积成显著的延迟。
  2. HTTP请求处理:处理HTTP请求涉及到多个层级的处理,包括网络IO、Spring MVC的DispatcherServlet、Controller的调用、数据绑定、模型渲染(尽管这里是void方法,但流程依然存在)、视图解析(尽管未使用)等。这些步骤在main方法中是不存在的。
  3. 线程管理和上下文切换:在Web服务器(如Tomcat)中,HTTP请求通常由服务器管理的线程池中的线程处理。线程管理(如线程的创建、销毁、上下文切换)以及可能的线程同步或锁等待都可能导致额外的开销。
  4. I/O性能差异:虽然这不太可能是导致如此大差异的主要原因,但不同环境下的文件系统I/O性能(如缓存、磁盘速度等)可能会有所不同。
  5. 日志和监控:Spring框架和底层服务器可能会进行额外的日志记录和监控,这些活动也会消耗时间。
  6. JVM热加载和JIT编译:在main方法中,JVM可能会更快地达到最佳性能状态(即JIT编译优化),因为main方法通常是一次性执行的。而在Web应用中,JVM需要持续运行并处理多个请求,这可能导致性能表现不同。

针对你的情况,虽然你的测试代码是在控制器中执行,但性能差异很可能是由于Spring MVC处理HTTP请求时的额外开销,以及可能存在的JVM性能优化差异。

为了更准确地评估性能,你可以考虑:

  • 在控制器中使用更精确的时间测量工具(如System.nanoTime())。
  • 分离测试,仅测量encode方法的执行时间,排除Spring MVC框架的干扰。
  • 评估并优化Spring MVC的配置和设置,以减少不必要的开销。
  • 检查和优化JVM参数,特别是与垃圾回收和JIT编译相关的参数。
  • 监控和分析系统资源使用情况,如CPU、内存和磁盘I/O,以查找可能的瓶颈。
 类似资料:
  • 问题内容: 我使用java for循环进行了一些运行时测试,并发现了一种奇怪的行为。对于我的代码,我需要原始类型(例如int,double等)的包装对象来模拟io和输出参数,但这不是重点。只是看我的代码。具有字段访问权限的对象如何比原始类型更快? 优先类型的循环: 结果: MicroTime原语(最大值:= 10000.0):110 MicroTime原语(最大值:= 100000.0):1081

  • 当代码在运行时,它所在的执行环境非常重要。 执行上下文 在 JavaScript 中,执行上下文与执行环境关系密切,它与函数和变量的声明息息相关,通常认为有两种执行上下文: 全局上下文——代码首次执行的默认环境; 函数上下文——当代码执行进入函数体中。 让我们来看一段包含这几种执行上下文的代码: // 全局上下文​var hello = 'Hello!';​function introduce()

  • 服务发布 服务发布过程涉及到三个类 RegistryConfig ,ServerConfig ,ProviderConfig 。 1. RegistryConfig RegistryConfig registryConfig = new RegistryConfig() .setProtocol("zookeeper") .setAddress("1

  • } 链接:https://www.hackerrank.com/challenges/java-string-compare/problem

  • 本文向大家介绍axios为什么能在浏览器中环境运行又能在node中环境运行?相关面试题,主要包含被问及axios为什么能在浏览器中环境运行又能在node中环境运行?时的应答技巧和注意事项,需要的朋友参考一下 源码中defaults.js文件里有getDefaultAdapter这个方法,用来判断环境。如果是浏览器就实例new XMLHttpRequest()来发送请求响应服务,node环境就引用h

  • 我对python中双for循环的使用感到困惑,这是我的代码: 输出如下: 它只对外循环的第一个值执行内循环,为什么会发生这种情况?我怎样才能让它在第一个和第二个变量的所有组合上循环?