昨天在群里跟人讨论关于String累加的问题,貌似没有人能特别准确的知道是一个什么样的情况,今天我通过jclasslib (PS:从
http://zangxt.iteye.com/搞到的好东西)来检测一下编译器是如何进行字符串累加的,我们先写一段代码:
package francis;
public class TestString {
public static void main(String[]args) {
String s = "";
for(int i = 0; i < 1000; i++) {
s += i;
}
System.out.println(s);
}
}
很简单,貌似网上也能给出一个大概的结论,但是我们还是亲手看一下编译后的代码:
我们可以看到上面的程序被编译成了22行的代码,我们注意看一下第6行到第18行,这是整个for循环所执行的代码,我们会很明显的看到,每次循环都会执行第6行的代码,也就是每次都会新建了一个StringBuilder对象,这多么浪费性能啊。
这就很明显了,每一次字符串的拼接,编译器都是通过新建StringBuilder对象来完成的。
哎,如果编译器足够智能,将新建StringBuilder对象放到循环之外,就不用我们去操心性能问题,但是,貌似目前编译器还办不到。所以我们手动的新建StringBuilder是比较好的方案:
package francis;
public class TestString {
public static void main(String[]args) {
String s = "";
StringBuilder sb = new StringBuilder(s);
for(int i = 0; i < 1000; i++) {
sb.append(i);
}
s = sb.toString();
System.out.println(s);
}
}
为了确定是否真的达到效果,我们来看一下这次编译后的代码:
这次循环的代码是在11~18行,而创建StringBuilder对象是在第三步执行。这样就避免了编译器会每个循环都新建一个StringBuilder对象了。比较好的习惯就是当连接字符串操作比较多的时候直接手动新建StringBuilder对象.
那有人可能会问了,String的每次拼接都是利用创建StringBilder对象来处理么? 实践乃检验真理的唯一方法:
先写代码:
package francis;
public class TestString {
public static void main(String[]args) {
String a = "a" + "b" + "c";
String b = a + "b";
String c = a + b;
System.out.println(a + b + c);
}
}
然后再看一下编译后的结果,由于比较长,我分成两张图片:
很显然,有四个new StringBuilder操作。基本可以得出结论:需要字符串连接的时候,如果没有可用的对应的StringBuilder就会去新建。因此字符串操作还是推荐自己手动去new StringBuilder,不能依赖编译器的优化。
当然会有很多其它情况,比如我在第三行代码后面加一个c+=a;a+=b;会产生什么样的情况呢?实践乃检验真理的唯一方法,自己去检测吧~~
分享到:
相关推荐
一、广播变量和累加器 通常情况下,当向Spark操作(如map,reduce)传递一个函数时,它会在一个远程集群节点上执行,它会使用函数中所有变量的副本。这些变量被复制到所有的机器上,远程机器上并没有被更新的变量会向...
public static void main(String[] args) { int t = 0; for (int i = 1; i ; i++) { t = i + 100; for (int j = 1; j ; j++) { if (t == j * j) { t = t + 168; for (int p = 1; p ; p++) ...
一、自定义排序 自定义排序 Spark对简单的数据类型可以直接排序,但是对于一些复杂的条件就需要...case class Girl(name:String,faceValue:Int,age:Int) object myOrder{ implicit val girlOrdering=new Ordering[Gi
将累加器acc初始化为0 遍历c[]以获取单个字符代码c : 如果65 <= c <= 90 ,则让i等于(1 + c) - 65 如果97 <= c <= 122 ,则让i等于(1 + c) - 97 如果48 <= c <= 57 ,则让i等于(27 + c) - 48...
此函数中遍列所有数据行,通过Replace替换标签生成Excel行,然后将行数据累加赋值到一个字符串 代码如下:string excelString = “”; foreach(var item in list){ excelString += string.Format(“….{0}”,list....
CMPXCHG 比较并交换操作数.( 第二个操作数必须为累加器AL/AX/EAX ) XADD 先交换再累加.( 结果在第一个操作数里 ) XLAT 字节查表转换. ── BX 指向一张 256 字节的表的起点, AL 为表的索引值 (0-255,即 0-FFH); 返回...
编写一个类实现银行帐户的概念,包括的属性有“帐号”、“储户姓名”、“地址”、“存款余额”,包括的方法有“存款”、“取款”、“查询”、“计算利息”、“累加利息”等。 二、实验要求 1) 改写上面的类,增加...
#include <string.h> #define MAX_BUFF 256 void main(int argc,char* argv[]) { FILE* stream; char buff[MAX_BUFF]; //缓冲区数组 最大256个字符 long sum=0; //累加器 char nstring[5]; //待转换成数字进行...
Java中 List《map》把里面map中某个key相同记录的其他key 的 value 合并 Java中 List《map》把里面map中某个key相同记录的其他key 的 value 合并
一、solidity中,映射的关键字为mapping,首先我们先来定义两个mapping, mapping(address =>uint) idmapping和mapping(uint =>string) namemapping。idmapping用来表示地址变量和整型变量的对应关系,在注册过程中...
代码如下:/// <summary> /// 汉字转拼音缩写 /// </summary> /// ”str”>要转换的汉字字符串</param> /// 拼音缩写</returns> public string GetPYString(string str) { string tempStr = “”; foreach(char c in ...
//如果和上次生成时间不同,重置sequence,就是下一毫秒开始,sequence计数重新从0开始累加 } lastTimestamp = timestamp; long suffix = (datacenterId ) | (workerId ) | sequence; String datePrefix = ...
pm1 = "选择所有累加的数:" pm2 = "选择所有加数:" Case "2" pm1 = "选择所有被减数:" pm2 = "选择所有减数:" Case "3" pm1 = "选择所有累乘数:" pm2 = "选择所有乘数:" Case "4" pm1 = "选择所有被除数:" pm...
private static string IntToIP(long ip_Int) { long num = (long) ((ip_Int & 0xff000000L) >> 0x18); if (num ) { num += 0x100L; } long num2 = (ip_Int & 0xff0000L) >> 0x10; if (num2 ) { num2 += ...
大文件拷贝实例源码,学习关于IO文件流、多线程相关使用做参考。 private void button4_Click(object sender, EventArgs e) { this.progressBar1.Value = 0; this.label1.Text = "0%"; if (!File.Exists(this....
public static void main(String[] args) throws IOException { test4(); } //创建临时文件 文件名称不能太短 private static void test4() throws IOException { File f = File.createTempFile("abc", "....
Spring boot整合分布式缓存Redis,包含redission对分布式数据结构list,string,hashmap,zset,set和对象的读写实例 包含一个redission的分布式可重入锁RLock使用实例 分布式对象:地理空间对象、分布式累加器。
3、由大到小重新排列信源 4、实现信源概率的叠加 5、计算码长l 6、编码 7、计算平均码长pl、信源熵Hx以及编码效率q 三、源程序: #include<iostream> #include<math.h> #include<string> using namespace std;...
由于数字无法用一个整形变量存储,很自然的想到...为了节约空间,所有的中间结果直接在m+n的辅存上进行累加。 C++实现大数相乘代码如下: #include #include<string> using namespace std; string BigNumMultiply(str
至少有一個操作數為寄存器,段寄存器不可作為操作數) CMPXCHG比較並交換操作數.( 第二個操作數必須為累加器AL/AX/EAX ) XADD 先交換再累加.( 結果在第一個操作數裡 ) XLAT (TRANSLATE) 字節查表轉換. <br...