关于软件构造-lab5性能优化中的一些问题

软件构造实验5:Lab-5 Static and Dynamic Code Analysis and Code Optimization,Java I/O Performance Optimization 一项中要求程序读取几个大概30mb左右40万行的txt文件,使用文件中的数据构建graph并显示,主要考察对代码的性能的分析和优化。

使用未修改前的代码,程序运行一次从开始读取文件到数据写入graph再到输出graph结束,整个流程大概需要10分钟左右。因为之前从来没有跑过这么大的文件,所以个人认为这个耗时还算正常,直到发现别人的代码几乎是在几秒钟之内时才发现自己的代码存在很大的缺陷。

俗话说,写代码容易改代码难,本人为了优化这个程序,使得运行时间从10分钟到几秒实在是煞费苦心,不知道有没有别的小伙伴和我碰到同样的问题。

经过多次的检查,我发现限制代码运行速度的原因主要有两点。

第一点出现在数据写入graph的过程中,也就是factory工厂类中(原本以为读取文件耗时,但其实bufferreader按行读取文件速度很快只用了几百ms而已,而正则切割部分耗时也很短),原本认为运行速度的瓶颈在于用读取的数据构建点和边这一部分,其实不然,真正问题的关键在于vertex和edge存入graph的这一环节,而这一问题的原因是出在graph存储vertex和edge的方式上。

之前为了便于检索,使用的存储方式是Hashset,然而hashset存在一个致命的缺陷,当数据量较小时还没有问题,可当数据量过大时hashset的存储会出现问题。hashset集合存在大小,即存储的数据量上限,如果最初没有设置上限大小的话,默认的大小自然不可能有多大。当存储的数据量超出上限时,hashset会自动倍数扩大,这时集合set1就被更大的set2替代,而原本set1的数据自然不会直接出现在set2中,于是在扩大时set1会把存储的所有数据取出放入内存中,再重新放入set2中。这一部分不仅耗费了时间同时占用内存,降低了代码性能。

第二点出现在graph的显示环节,因为个人使用的是GUI,在输出graph时要将需要显示的数据写到两个String类型的数据中然后输出,按理说单纯的String类型数据写入应该并不耗时,其实不然,这时由于java的特性。

在java中,假设String a = "波澜哥"; String b = "面筋哥"; a + = b;

按理说现在在内存中应该只有,a = “义结筋澜”和 b = “面筋哥”这两个数据,其实不然内存中存储了a(过去) = “波澜哥”,a(现在) = “义结筋澜”和 b = “面筋哥"这三个数据。

当数据量不大的时候还好,可当40万行的数据对你的代码进行狂轰乱炸时,占用的内存量就有点恐怖了。

因此我们需要一个很大的String类型的数据时,可以使用StringBuffer这种方法。

比如StringBuffer a = new StringBuffer("波澜哥");

      a.append("面筋哥");

     a.toString();

此时内存中只会存在a.toString() = “义结筋澜”这一数据,就不会存在过多的内存占用。

虽然只是两点,但对性能的影响还是非常大的,运行时间直接从10分钟变成了几秒,这就很现实了。

说实话,java的一些特性是真的让人防不胜防,需要学习的还很多啊!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值