`

避免创建不必要的对象

阅读更多

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自动化测试的效率和准确性至关重要。通过对虚拟对象集合的有效管理和合理使用,可以显著提升测试脚本的质量,...

    JavaScript对象创建的九种方式

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

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

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

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

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

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

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

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

    例如,通过避免不必要的对象创建,或者使用池化技术来重用对象,可以提高程序的效率。 总的来说,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. **创建...

    编写高效优雅Java程序.pdf

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

    Matlab面向对象编程

    通过抽象,我们可以忽略不必要的细节,只关注问题的关键部分。 2. 封装:封装是指隐藏对象的内部实现细节,只暴露操作接口供外界访问。在MATLAB中,通过类和对象实现封装。类定义了对象的属性和方法,而对象是类的...

Global site tag (gtag.js) - Google Analytics