`

避免创建不必要的对象

阅读更多

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开发中,避免创建不必要的对象对于优化应用性能和提高用户体验至关重要。对象的创建涉及到内存分配,即使有垃圾回收机制,频繁的对象创建仍然可能导致内存压力增大,进而影响应用的响应速度。以下是一些...

    在js中创建类和对象

    这种混合方法通常不推荐,因为它在内存管理上与传统的工厂方法和构造函数有相同的问题,可能会导致不必要的内存消耗。 6. 修改对象 通过修改对象的`prototype`,我们可以向对象添加新的方法或替换现有方法。例如,...

    C# 利用反射动态创建对象

    在C#编程中,反射是一种强大的机制,允许在运行时检查和操作程序集、类型、方法、属性等元数据。利用反射,我们可以动态地创建对象,这...然而,理解反射的工作原理和潜在的问题至关重要,以避免不必要的错误和困扰。

    sap权限对象的创建和使用

    在SAP系统中,权限管理是企业数据安全的重要组成部分,其中权限对象扮演着核心角色。权限对象是SAP授权机制的基础,...理解并正确实施权限管理,能确保企业数据的安全,同时避免不必要的系统访问限制,提高工作效率。

    使用类的对象还是指针

    例如,在dialog框类中,我们可以使用new关键字创建对象指针来创建一个非模式对话框,并在需要的时候才创建对象,以避免不必要的内存占用。 使用类的对象还是指针取决于具体的应用场景和需求。如果变量的个数较少且...

    QTP:虚拟对象需要注意的两点

    因此,在设计测试脚本时,应尽量避免不必要的虚拟对象使用。 总之,正确理解和使用虚拟对象对于提高QTP自动化测试的效率和准确性至关重要。通过对虚拟对象集合的有效管理和合理使用,可以显著提升测试脚本的质量,...

    effective Java(第3版)各章节的中英文学习参考(已完成).zip

    5 条优先依赖注入而不是硬连线资源(依赖注入硬件连接资源)第 6 条避免创建不必要的对象(避免创建不必要的对象)第 7 项消除过时的对象引用(排除时的对象引用)第8条避免使用终结器和清除器(避免使用终结器和...

    JavaScript对象创建的九种方式

    这样可以减少不必要的属性复制,提高性能。 8. **寄生构造函数模式**: 这种模式创建一个函数,该函数内部创建一个新对象,然后在新对象上执行一些操作,最后返回这个新对象。常用于创建复杂对象或需要返回不同类型...

    易语言创建互斥对象禁止重复运行模块

    总的来说,"易语言创建互斥对象禁止重复运行模块"是通过利用互斥对象这一系统级别的同步机制,保证了程序在单个系统实例中的唯一性,避免了不必要的资源浪费和潜在的冲突问题。这样的模块对于需要防止多实例运行的...

    Java基础:减少对象的创建提高java性能

    6. 利用编译器优化:现代的Java编译器(如JIT)会进行一些运行时优化,如逃逸分析,识别出某些对象不会逃逸出当前作用域,从而避免不必要的对象创建。 总的来说,减少对象创建是Java性能优化的重要策略,但这需要在...

    浅析在javascript中创建对象的各种模式_.docx

    然而,构造函数模式的一个问题是每个实例都会有自己的`logName`方法副本,这可能导致不必要的内存消耗。 3. **原型模式**: JavaScript中的对象可以通过原型链共享属性和方法。对象的`__proto__`(或`Object....

    浅析Java语言中对象的创建过程.zip

    例如,通过避免不必要的对象创建,或者使用池化技术来重用对象,可以提高程序的效率。 总的来说,Java中对象的创建是程序运行的基础,理解这一过程对于编写高效、可靠的代码至关重要。通过深入学习,开发者可以更好...

    Java对象池技术的原理及其实现

    为了减少这些不必要的开销,引入了对象池技术。 #### 对象池技术的基本原理 对象池技术的核心思想在于通过缓存和共享机制来重复使用已创建的对象,而非每次都需要重新创建新的实例。这种方式显著降低了对象创建和...

    java性能调优-jvm创建对象和-performance-createobj-allocationmemory.zip

    2. **减少对象创建**:尽量复用对象,减少不必要的new操作,例如使用StringBuilder而非String进行字符串拼接。 3. **TLAB优化**:利用线程私有的分配缓冲区,减少多线程环境下的内存竞争。 4. **对象初始化优化**...

    【原】unity 不销毁对象的处理

    9. **代码优化**:编写高效的代码,减少不必要的计算和更新。使用`StartCoroutine`和`yield`关键字可以实现异步操作,避免阻塞主线程。 10. **利用Unity的内置系统**:如Unity的物理系统、粒子系统等,它们内部优化...

    C++l临时对象

    在这种情况下,C++编译器优化了创建临时对象的过程,直接以相同的参数构造目标对象,避免了不必要的临时对象创建。 3. **函数返回对象值**:当函数返回一个对象值时,会创建一个临时对象用于存储返回的对象。例如...

    .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 最快...

    深刻理解对象设计及面向对象设计

    同时,要遵循接口隔离原则,使接口只包含相关联的职责,避免提供不必要的功能。 GRASP,全称为General Responsibility Assignment Software Principles,是一组面向对象设计的指导原则,包括以下几点: 1. **创建...

    面向对象的JavaScript.doc

    这样,每个实例都有自己独立的私有属性,而共享公共方法,有效地避免了值的不必要同步。 除了以上模式,JavaScript还支持**类式继承**和**委托继承**等概念。类式继承通过`prototype`链实现,一个对象可以继承另一...

Global site tag (gtag.js) - Google Analytics