知识大全 如何让你的程序运行的更快
Posted 知
篇首语:时代各有不同,青春一脉相承。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 如何让你的程序运行的更快相关的知识,希望对你有一定的参考价值。
在总体的框架设计确定以后 多注意一些编程细节 积少成多 可以获得更佳的性能 让程序跑的更快! 前些天同事优化代码时提到了String和StringBuffer 仔细想想 发现自己也就是知道个大概 所以查了 一下资料 文章中有错误的地方你可一定要告诉我啊 呵呵^+^ 一 介绍 String:非可变类(immutable) 一旦创建就不能再被改变 StringBuffer:可变类 创建之后可以被改变 何谓非可变类? 简单说 非可变类的实例是不能被修改的 每个实例中包含的信息都必须在该实例创建的时候就提供出来 并且在对象的整个生存周期内固定不变 非可变类好处 状态单一 对象简单 便于维护 通常是线程安全的 用户可以共享非可变对象 甚至可 以共享它们的内部信息 二 创建字符串 两种方法 String s = hello ; String s = new String( hello ) 哪种方式性能更好? 例 : //create String without new keyword longstartTime =System currentTimeMillis() for(inti= ;i< ;i++) String str = hello ; longendTime =System currentTimeMillis() System out println( create String without new keyword : +(endTime startTime )+ milli seconds ) //create String with new keyword longstartTime =System currentTimeMillis() for(inti= ;i< ;i++) String str = newString( hello ) longendTime =System currentTimeMillis() System out println( create String with new keyword : +(endTime startTime )+ milli seconds ) 输出结果为(注 程序的输出结果也许和你的结果不同 但是总体趋势应该是一致的) create String without new keyword : milli seconds create String with new keyword : milli seconds 结论 创建字符串变量时尽可能不使用new关键字 说明 虽然两个语句都是返回一个String对象的引用 但是jvm对两者的处理方式是不一样的 对于第一种不用new关键字创建String对象 JVM首先会在内部维护的滞留字符串中通过String的equels方法查找是对象池中是否存放有该 String对象 如果有 返回已有的String对象给用户 而不会在heap中重新创建一个新的String对象 如 果对象池中没有该String对象 JVM则在heap中创建新的String对象 将其引用返回给用户 同时将该引 用添加至滞留字符串中 对于第二种使用new关键字创建String对象 JVM会马上在heap中创建一个String对象 然后将该对象的引用返回给用户 JVM是不会主动把该 对象放到滞留字符串里面的 除非程序调用 String的intern()方法 JVM为字符串自变量维护一些唯一的String对象 程序员不需要为字符串自变量而发愁 但是使用new关键 字可能会在内存中创建重复的String对象 你不必为此而烦恼 intern()方法可以帮你解决问题 String intern() 检查字符串对象的存在性 如果需要的字符串对象已经存在 那么它会将引用指向已 经存在的字符串对象而不是重新创建一个 例 : String str = world ; /*JVM在滞留字符串中找不到值为 world 的字符串 就在堆上创建一个string对象 并将该对象的引用加入到滞留字符串中*/ String str = newString( world ) /*JVM在堆上重新创建一个值为 world 的字符串 此时堆上有两个值为 world 的字符串*/ if(str ==str ) System out println( str == str ) else System out println( str != str ) //输出 str != str String str = world ; /*JVM在发现滞留字符串中存在 world 对象 因此返回str 指向的对象给str 即str 和str 是指向同一个对象的引用*/ if(str ==str ) System out println( str == str ) else System out println( str != str ) //输出 str == str str =str intern() /*此时 JVM发现滞留字符串中已经存在 world 对象 因此返回str 指向的对象给str 即str 和str 是指向同一个对象的引用*/ if(str ==str ) System out println( after intern() str == str ) else System out println( after intern() str != str ) //输出 after intern() str == str 结论 如果使用new关键字创建了字符串变量 则尽可能使用intern()方法 上面的例子执行正是用到了string对象的不可变性质 既然string对象一旦创建就不可以改变 那么多个 引用指向同一个对象就不会对彼此产生影响 三 字符串连接 你可以使用+操作符或者ncat()或者StringBuffer append()等办法来连接多个字符串 哪 一种方法性能最佳? 如何选择取决于两种情景 第一种情景 需要连接的字符串是在编译期间决定的 还是在运行期间决定 第二种情景 你使用的是 StringBuffer还是String 通常程序员会认为StringBuffer append()方法会优于+操作符或 ncat()方法 但是在一些特定 的情况下这个假想是不成立的 ) 第一种情景 编译期间决定VS运行期间决定 //test the string Concatenation longstartTime =System currentTimeMillis() for(intk= ; k< ; k++) String str = this is + a test + for string concatenation ; longendTime =System currentTimeMillis() System out println( string concatenation using + : +(endTime startTime )+ milli seconds ) longstartTime =System currentTimeMillis() for(intk= ; k< ; k++) String str = this is ; ncat( a test ) ncat( for string concatenation ) longendTime =System currentTimeMillis() System out println( string concatenation using concat() : +(endTime startTime )+ milli seconds ) longstartTime =System currentTimeMillis() for(intl= ; l< ; l++) StringBuffer sb = newStringBuffer() sb append( this is ) sb append( a test ) sb append( for string concatenation ) longendTime =System currentTimeMillis() System out println( string concatenation using append() : +(endTime startTime )+ milli seconds )
上面代码的输出结果 string concatenation using + : milli seconds string concatenation using concat() : milli seconds string concatenation using append() : milli seconds 很有趣 +操作符比StringBuffer append()方法要快 Why? 这是因为编译器对简单的字符串进行了优化 即使使用new关键字来创建String对象的时候也是如此 例 如 编译前 String str = this is + a test + for string concatenation ; 编译后 String str = this is a test for string concatenation ; 这里String对象在编译期间就决定了而StringBuffer对象是在运行期间决定的 运行期间决定需要额外的 开销 结论 如果字符串在编译期间就可以决定它的值 则字符串拼接的时候 + 操作符效率更高 简单的 认为append()效率高于 + 是错误的 ) 第二种情景 StringBufferVSString //string concatenation using += longstartTime =System currentTimeMillis() String str = hello ; for(inti= ; i< ; i++) str += hello ; longendTime =System currentTimeMillis() System out println( string concatenation using += : +(endTime startTime )+ milli seconds ) //string concatenation using append() longstartTime =System currentTimeMillis() StringBuffer sb = newStringBuffer( hello ) for(inti= ; i< ; i++) sb append( hello ) longendTime =System currentTimeMillis() System out println( string concatenation using append() : +(endTime startTime )+ milli seconds ) 上面代码的输出结果 string concatenation using += : milli seconds string concatenation using append() : milli seconds 结论 避免使用 += 来构造字符串 虽然两者都是在运行期间决定字符串对象 但是使用+=操作符会产生更多的临时对象 在上例中 由于String类是不可变的 所以进行字符串拼接的时候 每循环一次就会产生临时对象来保存 str 和 hello 的值 之后创建一个临时的StringBuffer对象 并调用其append()方法来完成字符串的 拼接 最后调用toString()方法 将临时StringBuffer对象转为String再赋值给str 此时str 已经改变 指向了新的对象 ) 第三种情景 设置StringBuffer的容量来提升性能 longstartTime =System currentTimeMillis() StringBuffer sb = newStringBuffer( hello ) for(inti= ; i< ; i++) sb append( hello ) longendTime =System currentTimeMillis() System out println( string concatenation using append() : +(endTime startTime )+ milli seconds ) //set the StringBuffer capacity longstartTime =System currentTimeMillis() StringBuffer sb = newStringBuffer( hello ) sb ensureCapacity( ) for(inti= ; i< ; i++) sb append( hello ) longendTime =System currentTimeMillis() System out println( string concatenation using append() after set the StringBuffer capacity : milli seconds ) 上面代码的输出结果 string concatenation using append() : milli seconds string concatenation using append() after set the StringBuffer capacity : milli seconds 结论 声明StringBuffer对象的时候 指定合适的capacity 会提升程序性能 )使用StringBuffer的构造函数来设定它的初始化容量 StringBuffer(int length) )使用ensureCapacity(int minimumcapacity)方法在StringBuffer对象创建之后设置它的容量 首先我们看看StringBuffer的缺省行为 然后再找出一条更好的提升性能的途径 StringBuffer的缺省行为 StringBuffer在内部维护一个字符数组 当你使用缺省的构造函数来创建StringBuffer对象的时候 StringBuffer的容量被初始化为 个字符 也就是说缺省容量就是 个字符 当StringBuffer达到最大容 量的时候 它会将自身容量增加到当前的 倍再加 也就是( *旧值+ ) 如果你使用缺省值 初始化之后接着往里面追加字符 在你追加到第 (原文是 其实是错误的 因为在追加到第 个字符的时候 容量不会发生变化 很抱歉 以后会更严谨一些^+^)个字符的时候它会将容量增加 到 ( * + ) 当追加到 个字符的时候就会将容量增加到 ( * + ) 无论何事只要StringBuffer 到达它的最大容量它就不得不创建一个新的字符数组然后重新将旧字符和新字符都拷贝一遍 所以给 StringBuffer设置一个合理的初始化容量值 会提升程序的性能 但是为什么容量变化的时候是 *旧值+ 呢?有谁能告诉我么?查资料的时候没有找到 附 查资料的过程中发现了jdk 还提供了StringBuilder类 我是没有用过 不过也介绍一下好了 Java lang StringBuffer 线程安全的可变字符序列 类似于 String 的字符串缓冲区 但不能修 改 可将字符串缓冲区安全地用于多个线程 可以在必要时对这些方法进行同步 因此任意特定实例上的 所有操作就好像是以串行顺序发生的 该顺序与所涉及的每个线程进行的方法调用顺序一致 每个字符串缓冲区都有一定的容量 只要字符串缓冲区所包含的字符序列的长度没有超出此容量 就无需分配新的内部缓冲区数组 如果内部缓冲区溢出 则此容量自动增大 从 JDK 开始 为该 类增添了一个单个线程使用的等价类 即 StringBuilder 与该类相比 通常应该优先使用 StringBuilder 类 因为它支持所有相同的操作 但由于它不执行同步 所以速度更快 但是如果将 StringBuilder 的实例用于多个线程是不安全的 需要这样的同步 则建议使用 StringBuffer cha138/Article/program/Java/hx/201311/26749相关参考
net如今已经很流行成为赶时髦的程序员的首选但是大量刚刚接触net的程序员的确存在一定的认识误区这里先介绍一部分 一net程序再运行一次就会更快 许多人对此的解释是net程序第一次运行时会被编
net如今已经很流行成为赶时髦的程序员的首选但是大量刚刚接触net的程序员的确存在一定的认识误区这里先介绍一部分 一net程序再运行一次就会更快 许多人对此的解释是net程序第一次运行时会被编
人怎样才能活得更轻松、更快乐每一个人的一生中都会有很多不顺心的事,但是只要记住以下的话那样你的生活才会天天开心!感激遗弃你的人,因为他教会了你独立.感激伤害你的人,困为他磨练了你的心态.感激绊倒你的人
如今已经很流行成为赶时髦的程序员的首选但是大量刚刚接的程序员的确存在一定的认识误区这里先介绍一部分 一程序再运行一次就会更快 许多人对此的解释是程序第一次运行时会被编译成本地代码所以再次运行会
假如你目前运行的是Oracleg或更高的版本那么你现在就可以用新的utl_mail工具包从你的PL/SQL应用程序来发送电子邮件了(注释如果你的应用程序使构建在Oraclei的基础之上前提是运行维
知识大全 失恋的伤痛多久才能愈合?怎样才能更快的愈合?拜托了各位 谢谢
失恋的伤痛多久才能愈合?怎样才能更快的愈合?拜托了各位谢谢或许是永远也愈合不了.如果是真的付出真心的话.但我希望那个伤害你的家伙.不是你的命定恋人.然后你可以找到属于你的真正幸福.祝你幸福哦.麻烦采纳
知识大全 java中的分布式是什么意思,和在同一台电脑上运行的程序有什么区别?
java中的分布式是什么意思,和在同一台电脑上运行的程序有什么区别?分布式,你可以理解为子节点可以独立运行例子:你开一家店,你就是服务器-客户端的架构,哪天你的生意壮大了,你就开了十家分店,这就相当于
知识大全 如果你的好朋友让你改变一些,让你不要故作坚强,你会怎么做
如果你的好朋友让你改变一些,让你不要故作坚强,你会怎么做三人行必有我师。如果你确实故作坚强,那么说明朋友心疼你,希望能为你分担,你有心里话可以跟他说如果时间让你从来,,让你改变一件事,,你会改变那什么
让你的.NET应用成为一个灰色盒子 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 与已经摸爬滚打
想学写作该从哪开始努力学习写作,告诉你三个练习的方法,可以在较短时间内得到较大的提高,当然,文字积累是长期的过程,告诉你的方法是让你更快的提升语感和入门,达到一个较好的起点。1.买一些中考或者高考的现