随着时间的发展,现在的虚拟机技术越来越成熟了,在有些情况下,Java,.Net等虚拟机密集计算的性能已经和C++相仿,在个别情况下,甚至还要更加优秀。本文详细分析几个性能测试案例,探讨现象背后的原因。

来看两个简单的测试用例。如下图所示,均是循环5000次,操作 len = 1000000 的连续内存,计算执行时间。左侧为test1,右侧为test2。

类似的程序在 .net core 3.0 Preview6下测试。

测试结果对比如下:

我们可以看见,对于test1,C++版本要快很多,对于test2,C#版本和C++版本性能相当,甚至略快。

为什么会出现这种现象呢?下面来具体分析:

test1 的循环的赋值是位置无关的,因此,编译器可以通过SIMD等并行计算指令来优化,test2 的循环的赋值是位置相关的,编译器很难使用SIMD等并行计算指令来优化。通过上面的结果可以猜测,VC编译器,对test1进行了并行优化,而.net core 3.0 preview6 没有对test1 进行并行优化。

我们来验证这一猜测。.net core 3.0 提供了对SIMD 指令的支持,下面手动对test1进行并行优化,测试性能:

结果是0.633s,接近于C++版本的0.441s。相对于优化前的2.289s,提速了3倍多。

同样的程序,我用 java 8 测试,结果大吃一惊:

test1 耗时 0.654s,和并行优化后的.net core近似,可见 jvm 虚拟机对此进行了并行优化。test2 耗时1.755s,比C++版本和.net core版本都要快,并且差距巨大!

显然,jvm对test2这种情况进行了特殊关照。要理解这一现象,就需要对Java虚拟机的机制有深入了解。HotSpot 虚拟机里内置了两个JIT编译器:Client Compiler和Server Compiler,简称为C1编译器和C2编译器。C1编译器将字节码编译为本地代码,进行简单、 可靠的优化,如有必要将加入性能监控的逻辑。C2编译会启用一些编译耗时较长的优化,甚至进行一些激进优化。

查找文献可知,默认情况下,当方法调用次数+循环回边次数超过10000、计数器是int等几个简单类型、步增是常量时,会触发C2编译优化。test2恰恰满足这三种情况!

下面我们再设计一个实验,将步增改为变量,看看测试结果:

由测试可知,将步增改为变量后,测试结果为6.163秒,和C++及 .net core 测试结果近似。

针对这个测试案例,可以猜测 C2 优化时进行了循环展开。下面,我们在 .net core 下手动展开循环,测试性能,验证我们的猜想:

测试结果为1.983s,近似java8的1.755s。猜想得到验证。

----

总结:随着JVM、.Net等虚拟机技术的发展,语言特性对高性能计算性能影响越来越低,对计算机体系结构、编译原理、虚拟机编译机制的理解,对性能的影响变得更为重要。

从三个语言(C++,Java,.Net)的几个性能测试案例来看性能优化的更多相关文章

  1. Java高级开发必会的50个性能优化细节

    在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身.养成良好的编码习惯非常重要,能够显著地提升程序性能. 1. 尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时 ...

  2. Java高级开发必会的50个性能优化的细节(珍藏版)

      在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身.养成良好的编码习惯非常重要,能够显著地提升程序性能. ● 1. 尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短 ...

  3. Java并发程序设计(十三)锁的性能优化

    锁的性能优化 一.优化注意事件 一)减少锁的持有时间 只在必要时进行同步,能明显减少锁的持有时间. 二)锁的细化 缺陷:当系统需要全局锁时,其消耗的资源会比较多. 三)锁的分离 比如读写分离锁 四)锁 ...

  4. Java面试准备十六:数据库——MySQL性能优化

    2017年04月20日 13:09:43 阅读数:6837 这里只是为了记录,由于自身水平实在不怎么样,难免错误百出,有错的地方还望大家多多指出,谢谢. 来自MySQL性能优化的最佳20+经验 为查询 ...

  5. JAVA架构之单点登录 任务调度 权限管理 性能优化大型项目实战

    单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任.单点登录在大型网站里使用得 ...

  6. Java GC 专家系列5:Java应用性能优化的原则

    本文是GC专家系列中的第五篇.在第一篇理解Java垃圾回收中我们学习了几种不同的GC算法的处理过程,GC的工作方式,新生代与老年代的区别.所以,你应该已经了解了JDK 7中的5种GC类型,以及每种GC ...

  7. 云时代架构阅读笔记一——Java性能优化(一)

    Java语言学习了这么长时间之后,自己对于Java编程的一些细节还是稍微有点总结,正好根据云时代架构中<Java高级开发必会的50个性能优化的细节(珍藏版)>来叙述一些我和里面的点比较相符 ...

  8. Java 性能优化的五大技巧

    要对你的 Java 代码进行优化,需要理解 Java 不同要素之间的相互作用,以及它是如何与其运行时的操作系统进行交互的.使用下面这五个技巧和资源,开始学习如何分析和优化你的代码吧. 在我们开始之前, ...

  9. java安全沙箱(三)之内置于Java虚拟机(及语言)的安全特性

    java是一种类型安全的语言,它有四类称为安全沙箱机制的安全机制来保证语言的安全性,这四类安全沙箱分别是: 类加载体系 .class文件检验器 内置于Java虚拟机(及语言)的安全特性 安全管理器及J ...

随机推荐

  1. 一步到位安装Centos7、配置VMware、连接Xshell

    1.创建虚拟机 1.0 创建新的虚拟机 1.0.1 选择自定义配置 打开VMware,点击创建新的虚拟机. 如下图所示:   1.0.2 选择虚拟机硬件兼容性 如下图所示:   1.0.3 安装客户操 ...

  2. Loadrunner做性能测试的主要步骤

    Loadrunner做性能测试的主要步骤: Loadrunner将性能测试过程分为计划测试.测试设计.创建VU脚本.创建测试场景.运行测试场景和分析结果6个步骤. 1) 计划测试:主要进行测试需求的收 ...

  3. 系统学习 Java IO (四)----文件的读写和随机访问 FileInputStream/FileOutputStream & RandomAccessFile

    目录:系统学习 Java IO---- 目录,概览 文件输入流 FileInputStream 这是一个简单的FileInputStream示例: InputStream input = new Fi ...

  4. 快速接入业务监控体系,grafana监控的艺术

    做一个系统,如果不做监控,是不完善的. 如果为做一个快速系统,花力气去做监控,是不值得的. 因为,我们有必要具备一个能够快速建立监控体系的能力.即使你只是一个普通开发人员! 个人觉得,做监控有三个核心 ...

  5. <h2>js数组操作大全(pop,push,unshift,splice,shift方法)</h2>

    ---恢复内容开始--- shift:删除原数组第一项,并返回删除元素的值:如果数组为空则返回undefined var a = [1,2,3,4,5]; var b = a.shift(); //a ...

  6. 🔨揭秘vue-sfc-cli: 组件研发利器

    前言 本文将揭示vue单文件组件的工具 vue-sfc-cli 的内涵,说明它是如何在整个组件研发流程中提升效率的. 本文可以看成是 

  7. Linux命令学习-cp命令

    Linux中,cp命令的全称是copy,主要作用是复制文件或文件夹,类似于Windows下的复制功能. 假设当前处于wintest用户的主目录,路径为 /home/wintest ,存在文件夹test ...

  8. 1.Solr安装与配置

    1.Solr安装 1:安装 Tomcat,解压缩即可. 2:解压 solr. 3:把 solr 下的dist目录solr-4.10.3.war部署到 Tomcat\webapps下(去掉版本号). 4 ...

  9. 操作xml练习

    案例1:获取指定节点的内容 public void XmlTest() { string xmlFileName=AppDomain.CurrentDomain.BaseDirectory+" ...

  10. Java基础之回味finally

    平时大家try…catch…finally语句用的不少,知道finally块一定会在try…catch..执行结束时执行,但是具体是在什么时候执行呢,今天我们一起来看下. public static ...