`

避免创建不必要的对象

阅读更多

Java中Sting很特别,有如下两种初始化方式:

(1).String s1 = “This isstring1”;

(2).String s2 = new String(“Thisis string2”);

第一种字符串初始化方式,当有多于一个字符串的内容相同情况,字符串内容会放在字符串缓冲池中,即字符串内容在内存中只有一份。

第二种字符串初始化方式,不论有没有字符串值相同,每次都会在内存堆中存储字符串的值。

如果一个方法中字符串的值都相同,调用100万次情况下第一种字符串初始化方式的内存占用率很低,性能非常高,而第二种方式的字符串初始化则会占用大量的内存.

看下面一个例子,直观感受创建不必要对象的性能危害:

 

[java] view plain copy
 
  1. public class Person{  
  2.     private Date birthDate;  
  3.     //判断是否是婴儿潮出生的人  
  4.     public boolean isBabyBoomer(){  
  5.     Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(“GMT”));  
  6.     //婴儿潮开始时间  
  7.     cal.set(1946, Calendar.JANUARY, 1000);  
  8. Date boomStart = cal.getTime();  
  9. //婴儿潮结束时间  
  10.     cal.set(1965, Calendar.JANUARY, 1000);  
  11. Date boomEnd = cal.getTime();  
  12. return birthDate.compareTo(boomStart) >= 0 && birthDate.compareTo(boomEnd) < 0;  
  13. }  
  14. }  

 

每次调用isBabyBoomer()方式时,都需要创建Calendar,TimeZone,boomStart和boomEnd四个对象,测试调用该方法1000万次,大约耗时32秒。

Calendar,TimeZone,boomStart和boomEnd四个对象是所有调用者共用的对象,只需创建一份即可,改进之后代码如下:

 

[java] view plain copy
 
  1. public class Person{  
  2.     private Date birthDate;  
  3.     private static final Date BOOM_START;  
  4.     private static final Date BOOM_END;  
  5.     static{  
  6.     Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(“GMT”));  
  7.     //婴儿潮开始时间  
  8.     cal.set(1946, Calendar.JANUARY, 1000);  
  9. BOOM_START = cal.getTime();  
  10. //婴儿潮结束时间  
  11.     cal.set(1965, Calendar.JANUARY, 1000);  
  12. BOOM_END = cal.getTime();  
  13. }  
  14.     //判断是否是婴儿潮出生的人  
  15.     public boolean isBabyBoomer(){  
  16. return birthDate.compareTo(BOOM_START) >= 0 && birthDate.compareTo(BOOM_END) < 0;  
  17. }  
  18. }  

 

经测试,调用1000万次,耗时大约130毫秒,性能提高250倍。

再看第二个例子,计算所有的int之和,代码如下:

 

[java] view plain copy
 
  1. public CalculateInt{  
  2.     public static void main(String[] args){  
  3.     Long sum = 0L;  
  4.     for(long i = 0; i < Integer.MAX_VALUE; i++){  
  5.     sum += i;  
  6. }  
  7. System.out.println(sum);  
  8. }  
  9. }  

 

由于sum是Long类型,而不是原始类型的long,因此总共进行了2的31次方不必要的类型自动封装(将原始类型的long封装为Long),总共耗时大约43秒。

将sum声明的由Long类型改为原始类型的long,由于省去了2的31次方不必要的类型自动封装,程序大概耗时6秒,性能提高7倍。

分享到:
评论

相关推荐

    Android中怎样避免创建不必要的对象

    所以避免创建不必要的对象对于Android开发尤为重要。 本文会介绍一些常见的避免创建对象的场景和方法,其中有些属于微优化,有的属于编码技巧,当然也有确实能够起到显著效果的方法。 使用单例 单例是我们

    .NET性能优化方法 学习笔记 (详细整理版)

    1.1.1 避免不必要的对象创建 1.1.2 不要使用空析构函数 ★ 1.1.3 实现 IDisposable 接口 1.2 String 操作 1.2.1 使用 StringBuilder 做字符串连接 1.2.2 避免不必要的调用 ToUpper 或 ToLower 方法 1.2.3 最快...

    编写高效优雅Java程序.pdf

    可以使用对象池来避免创建不必要的对象,但是要谨慎使用对象池,除非创建的对象是非常昂贵的操作。 3. 使类和成员的可访问性最小化:使类和成员的可访问性最小化可以提高程序的安全性和可维护性。 4. 使类不可变:...

    JavaScript中的new的使用方法与注意事项

    例如,我们可以使用一个工厂函数来创建多个对象,这可以帮助我们更方便地创建对象,同时也可以避免创建不必要的对象。 在 JavaScript 中的 new 操作符是一个非常重要的概念,它可以帮助我们更方便地创建对象、函数...

    request.getSession().doc

    * 在编写代码时,需要根据实际情况选择合适的 create 参数值,以避免不必要的会话创建或.NullPointerException 异常。 常见错误 在实际开发中,很多开发者都会犯以下错误: 1. 使用 getSession() 方法时,忽视了 ...

    2022年CORBA对象生命周期之实现和内存管理Java教程.docx

    驱除器必需保证伺服对象是常常被逐出的,以避开不必要的资源消耗。 CORBA 对象生命周期的实现和内存管理是 Java 教程中非常重要的一部分。通过对静态、瞬态和长久 Corba 对象的分类,以及伺服对象池模式的应用,...

    word2021组合或取消组合形状或对象.docx

    但同时,需要注意取消组合形状或对象的操作,避免出现不必要的麻烦。 Word 2021 中的组合形状或对象功能可以提高工作效率,提高工作质量。但是,需要正确地使用该功能,避免出现不必要的麻烦。

    Java中内存泄露及垃圾回收机制参照.pdf

    在传统的高级编程语言(例C++)中,对象的创建和回收均由程序员自行负责,如果创建了对象而忘记回收,则会造成内存泄漏,长此以往,程序运行的时候可能会生成很多不清除的垃圾,浪费了不必要的内存空间,有时还可能...

    详细介绍VisuBasic代码优化总结.docx

    Visual Basic(VB)代码优化是一个涉及多个方面的综合过程,旨在提高程序的性能、可读性和维护性。以下是一些常见的VB代码优化技巧和总结: ...8. **延迟加载对象**:仅在需要时才创建对象,避免过早初始化。

    .net性能优化宝典

    1.1.1 避免不必要的对象创建... 4 1.1.2 不要使用空析构函数 ★... 4 1.1.3 实现 IDisposable 接口... 4 1.2 String 操作... 5 1.2.1 使用 StringBuilder 做字符串连接... 5 1.2.2 避免不必要的调用 ToUpper 或...

    shscrap(用以打开ssh文件)

    SHS文件是一类特殊的OLE(ObjectLinkingandEmbedding,对象连接和嵌入)对象,可以由Word文档或Excel电子表格创建。一般在XP系统上发生,现在win7...建议各位在操作时最好知道是什么文件扩展名,避免造成不必要的麻烦。

    java7hashmap源码-Effective-Java-3th:Effective-Java-3th

    java7 hashmap源码 Effective Java 3th 索引 创建和销毁对象 考虑使用静态工厂方法代替构造方法 优点: 有名字 每次调用的时候,不一定要创建新的...避免创建不必要的对象 用 String str = "abcd";而不是String str= n

    WEB CAD中二次开发绘制任意线功能代码如何写?

    同时,为了避免出现不必要的重叠和绘制异常,可以在每次绘制前清空 Canvas 画布。 实现网页 CAD 绘制任意线的基本思路和代码要根据实际需求进行修改和扩展,比如增加颜色、宽度等属性选择,或者支持多种绘图模式(如...

    .NET性能优化方面的总结

    火龙果软件工程技术中心 从2004年底开始接触C#到现在也有2年多... 1.1.1避免不必要的对象创建 由于垃圾回收的代价较高,所以C#程序开发要遵循的一个基本原则就是避免不必要的对象创建。以下列举一些常见的情形。 1.

    g++中的局部静态变量的初始化机制及线程安全

    这是一种 lazy initialization 机制,能够避免在程序启动时进行不必要的初始化操作。 Meyers Singleton 模式是 C++ 中的一种经典的单例模式,它使用局部静态变量来实现单例对象的初始化。该模式的实现方式如下所示...

    Android应用开发之(性能优化)[收集].pdf

    避免创建不必要的对象对象创建永远不会是免费的。每个线程的分代GC 给零时对象分配一个地址池以降低分配开销,但往往内存分配比不分配需要的代价大。如果在用户界面周期内分配对象,就会强制一个周期性的垃圾回收,...

    从实例谈面向对象编程、工厂模式和重构

    我们发现一些不必要的设计时,还需要果断地删掉这些冗余代码。 引用内容 Public void BtnPlay_Click(object sender,EventArgs e) { IMediaFactory factory = null; switch (cbbMediaType.SelectItem.ToString()....

    力控与Oracle数据库的连接[整理].pdf

    在使用Oracle作为数据时,应先考虑随数据库软件所携带ODBC版本问题,避免不必要的麻烦。使用力控来创建数据库中的表,可以避免设置数据类型的“Precision”和“Scale”属性的麻烦。 六、总结 本文提供了详细的指导...

Global site tag (gtag.js) - Google Analytics