从三个语言(C++,Java,.Net)的几个性能测试案例来看性能优化
随着时间的发展,现在的虚拟机技术越来越成熟了,在有些情况下,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)的几个性能测试案例来看性能优化的更多相关文章
- Java高级开发必会的50个性能优化细节
在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身.养成良好的编码习惯非常重要,能够显著地提升程序性能. 1. 尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时 ...
- Java高级开发必会的50个性能优化的细节(珍藏版)
在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身.养成良好的编码习惯非常重要,能够显著地提升程序性能. ● 1. 尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短 ...
- Java并发程序设计(十三)锁的性能优化
锁的性能优化 一.优化注意事件 一)减少锁的持有时间 只在必要时进行同步,能明显减少锁的持有时间. 二)锁的细化 缺陷:当系统需要全局锁时,其消耗的资源会比较多. 三)锁的分离 比如读写分离锁 四)锁 ...
- Java面试准备十六:数据库——MySQL性能优化
2017年04月20日 13:09:43 阅读数:6837 这里只是为了记录,由于自身水平实在不怎么样,难免错误百出,有错的地方还望大家多多指出,谢谢. 来自MySQL性能优化的最佳20+经验 为查询 ...
- JAVA架构之单点登录 任务调度 权限管理 性能优化大型项目实战
单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任.单点登录在大型网站里使用得 ...
- Java GC 专家系列5:Java应用性能优化的原则
本文是GC专家系列中的第五篇.在第一篇理解Java垃圾回收中我们学习了几种不同的GC算法的处理过程,GC的工作方式,新生代与老年代的区别.所以,你应该已经了解了JDK 7中的5种GC类型,以及每种GC ...
- 云时代架构阅读笔记一——Java性能优化(一)
Java语言学习了这么长时间之后,自己对于Java编程的一些细节还是稍微有点总结,正好根据云时代架构中<Java高级开发必会的50个性能优化的细节(珍藏版)>来叙述一些我和里面的点比较相符 ...
- Java 性能优化的五大技巧
要对你的 Java 代码进行优化,需要理解 Java 不同要素之间的相互作用,以及它是如何与其运行时的操作系统进行交互的.使用下面这五个技巧和资源,开始学习如何分析和优化你的代码吧. 在我们开始之前, ...
- java安全沙箱(三)之内置于Java虚拟机(及语言)的安全特性
java是一种类型安全的语言,它有四类称为安全沙箱机制的安全机制来保证语言的安全性,这四类安全沙箱分别是: 类加载体系 .class文件检验器 内置于Java虚拟机(及语言)的安全特性 安全管理器及J ...
随机推荐
- 【MYSQL】mysql大数据量分页性能优化
转载地址: http://www.cnblogs.com/lpfuture/p/5772055.html https://www.cnblogs.com/shiwenhu/p/5757250.html ...
- jenkins获取GitLab的hook数据并处理
jenkins获取GitLab的hook数据并处理 jenkins安装Generic Webhook Trigger Plugin插件 {% asset_img Generic_Webhook_Trg ...
- C#8.0: 在 LINQ 中支持异步的 IAsyncEnumerable
C# 8.0中,提供了一种新的IAsyncEnumerable<T>接口,在对集合进行迭代时,支持异步操作.比如在读取文本中的多行字符串时,如果读取每行字符串的时候使用同步方法,那么会导致 ...
- websocket实现群聊和单聊(转)
昨日内容回顾 1.Flask路由 1.endpoint="user" # 反向url地址 2.url_address = url_for("user") 3.m ...
- kuangbin专题 专题一 简单搜索 Catch That Cow POJ - 3278
题目链接:https://vjudge.net/problem/POJ-3278 题意:人可以左移动一格,右移动一格,或者移动到当前位置两倍下标的格子 思路:把题意的三种情况跑bfs,第一个到达目的地 ...
- pdfminer获取整页文本
#! python2 # coding: utf-8 import sys from cStringIO import StringIO from pdfminer import pdfinterp ...
- Centos6.5安装Redis3.2.8
1 - Redis安装 redis安装 在网上一搜一大把,但是还是在这里想要能够统一吧,所以这个安装步骤是在Centos6.5 Minimal 上安装redis3.4.8,本次安装是在root 用户下 ...
- MyBatis 使用枚举或其他对象
From<Mybatis从入门到精通> 1.笔记: <!-- 6.3 使用枚举或者其他对象 6.3.1 使用MyBatis提供的枚举处理器 不懂: 因为枚举除了本身的字面值外,还可以 ...
- python菜鸟基础知识(二)
3.2 字符串格式化 a = "------------- 我爱涛 -------------" b = "name:" c = "age:" ...
- NOIp 2018 普及&提高组试题答案
你们考的咋样呢?在评论区说出自己的分数吧!