针对Java JIT的优化(转表工具:xresloader)

之前做了一个转Excel表到lua/二进制/json/xml的工具-xresloader。目的一方面是方便策划。另一方面是统一客户端和服务器的转表模式,并且要灵活适应环境变化。

最初做的时候考虑到既要方便Windows下策划和前端使用,又要方便后台部署在服务器上使用,甚至要集成在一些自动化的系统里。所以必须要跨平台。

并且需要对Excel操作比较好的Lib和对protobuf等各种协议操作比较方便的Lib。

所以综合考虑以后用了java来实现。

但是实际使用过程中,随着表格的数量越来越多,转换时间也越发地不可忍受。在做了简单地分析以后发现,在转换一个表格的时候,java载入jar包之后花了超过三分之二的CPU用于编译和编译优化java字节码。不到三分之一的CPU时间用于转表。而一次编译java字节码花费的时间要大约1秒钟左右。 这就意味着我们目前的70个表要花1分半中的时间编译java字节码,而实际转表只要不到半分钟。这果断是极大的CPU浪费并且等待时间太长了。

java的这个JIT功能对服务器程序是非常有用的,因为这样可以在编译期不需要像C++一样花费大量的时间,并且容易做跨平台的指令集抽象。实际开发中编译很频繁,java这个特性可以减少大量的开发中等待时间,而上线以后又能有比较好的运行效率。 但是这个特性放到命令行工具上就比较伤了,因为命令行工具一般都是执行次数频繁但是执行时间很短的,如果像这样每次运行去编译反而会浪费总体的资源和时间。最理想的情况是和_.Net Native_一样可以把它便以为本地应用。可惜java貌似还没这个功能。

而我尝试关掉java的JIT时,实际时间会更长,所以就有必要针对Java这个特性做一些特别的优化。 仍然是为了容易和其他工具集成,所以我这里设计成了可以通过stdin来获取多次转表的信息。还有一点就是要把单例的部分在下一次转换的时候清理掉。 然后批量转表工具xresconv-clixresconv-gui都接入新的转换方式。通过管道来控制子进程的标准输入,以此来控制转表内容。 实际优化后的效果相当明显。虽然我懒得把对比数据跑出来了,但是原先70个表每个需要超过1秒钟,4个并发任务总时间也会需要十几二十秒,而现在2个并发任务的情况下,总转换时间6秒左右。 现在的转换步骤里,转第一个表的时候大约需要1秒钟,然后剩下的前十个左右大约在0.2-0.4秒钟。再后面的速度就是”刷得一下“就结束了。 可以很明显地感受到java JIT的第一次编译优化,运行频繁以后的第二次更深度优化带来的性能提升。后面一批转表感觉上速度提升有_十倍_以上。

然后我测了一下2个并发任务和4个并发任务时的区别,2个并发任务的情况下更能发挥java的JIT优势,耗时6秒左右。而4个并发任务时虽然进程数更多,但是JIT优化的效果会降低很多,反而总时间在9秒左右。 而单线程时JIT效果最好,但是总时间感觉比2个并发任务略慢一点点。(我的机器是4核8线程的CPU,型号是至强 E3-1230 V2)

所以我把批量转表工具的默认最大并发度都限制到了2。 总的来说,这次的优化效果还是很明显的,虽然在批量转表的情况下还有一些优化空间(比如macro表几乎不变,可以缓存下来),下次有空再说吧。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏恰童鞋骚年

操作系统核心原理-5.内存管理(上):基本内存管理

操作系统的两个角色分别是魔术师和管理者,在管理者这个角色中,除了CPU之外,内存是操作系统要管理的另外一个重要资源。内存管理需要达到两个目标:一是地址保护,即...

10020
来自专栏腾讯大数据的专栏

大型web系统数据缓存设计

1. 前言 在高访问量的web系统中,缓存几乎是离不开的;但是一个适当、高效的缓存方案设计却并不容易;所以接下来将讨论一下应用系统缓存的设计方面应该注意哪些...

50060
来自专栏Java职业技术分享

如何使用SpringMvc处理Rest异常

若你的项目中已经在使用spring,然后你又需要提供rest接口,那么springmvc是一个不错的选择。

15000
来自专栏Java架构沉思录

单线程的Redis为什么这么快?

https://blog.csdn.net/xlgen157387/article/details/79470556

22230
来自专栏PHP在线

缓存更新的套路

看到好些人在写更新缓存数据代码时,先删除缓存,然后再更新数据库,而后续的操作会把数据再装载的缓存中。然而,这个是逻辑是错误的。试想,两个并发操作,一个是更新操作...

384130
来自专栏腾讯云流计算

Data Artisans Streaming Ledger ——流数据处理中串行化的ACID事务

Data Artisans Streaming Ledger,在data Artisans的River Edition上已经可用,提供串行化(一致性事务处理机制...

34510
来自专栏小怪聊职场

HTTP|GET 和 POST 区别?网上多数答案都是错的!

356100
来自专栏数据之美

玩转 SHELL 脚本之:Shell 命令 Buffer 知多少?

1、问题: 下午有同学问了这么一个问题: tail -n +$(tail -n1 /root/tmp/n) -F /root/tmp/ip.txt 2>...

45060
来自专栏企鹅号快讯

Golang 中的微服务-第一部分

介绍 Golang 中的微服务系列总计十部分,预计每周更新。本系列的解决方案采用了 protobuf 和 gRPC 作为底层传输协议。为什么采用这两个技术呢?我...

561100
来自专栏个人分享

面向消息的持久通信与面向流的通信

消息队列系统为持久异步通信提供多种支持,本质是提供消息的中介存储能力,这样就不需要消息发送方和接收方在消息传输过程中都保持激活状态。

11240

扫码关注云+社区

领取腾讯云代金券