我们知道,在JDK8及以下版本中,使用加号表示连接的字符串将被编译到StringBuilder中进行性能优化,但在JDK9之后,它将使用<code>java.lang.invoke实现。StringConcatFactory#makeConcatWithConstants方法。
但是,在反编译< code>java.lang.Object之后,可以看到其< code>toString方法仍然是使用StringBuilder实现的:
public java.lang.String toString();
descriptor: ()Ljava/lang/String;
flags: (0x0001) ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: new #1 // class java/lang/StringBuilder
3: dup
4: invokespecial #3 // Method java/lang/StringBuilder."<init>":()V
7: aload_0
8: invokevirtual #7 // Method getClass:()Ljava/lang/Class;
11: invokevirtual #13 // Method java/lang/Class.getName:()Ljava/lang/String;
14: invokevirtual #19 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: ldc #23 // String @
19: invokevirtual #19 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
22: aload_0
23: invokevirtual #25 // Method hashCode:()I
26: invokestatic #29 // Method java/lang/Integer.toHexString:(I)Ljava/lang/String;
29: invokevirtual #19 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
32: invokevirtual #35 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
35: areturn
LineNumberTable:
line 256: 0
LocalVariableTable:
Start Length Slot Name Signature
0 36 0 this Ljava/lang/Object;
翻看源代码,可以看到它还是用加号来连接三个部分:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
将相同的代码重写到一个类中进行编译:
public class Main {
public String fooString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
}
从反编译可以看出,仍然是用< code > Java . lang . invoke . stringconcatfactory # makeConcatWithConstants 方法实现的:
public java.lang.String fooString();
descriptor: ()Ljava/lang/String;
flags: (0x0001) ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
start local 0 // Main this
0: aload_0
1: invokevirtual #7 // Method java/lang/Object.getClass:()Ljava/lang/Class;
4: invokevirtual #11 // Method java/lang/Class.getName:()Ljava/lang/String;
7: aload_0
8: invokevirtual #17 // Method java/lang/Object.hashCode:()I
11: invokestatic #21 // Method java/lang/Integer.toHexString:(I)Ljava/lang/String;
14: invokedynamic #27, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
19: areturn
end local 0 // Main this
LineNumberTable:
LocalVariableTable:
Start Length Slot Name Signature
0 20 0 this LMain;
那幺,为什么在<code>Object</code>类中使用加号是使用<code>StringBuilder</code>实现的,而类<code>A</code>(如上所述)是使用<code>makeConcatWithConstants</codes>实现的?JDK提供的Object类的字节码是否与源代码不匹配,或者在编译时是否对Object类进行了特殊优化?
JEP里有解释强调我的
豁免。由于此功能使用核心库功能(java.lang.invoke)来实现核心语言功能(字符串串联),因此我们必须免除 java.base 模块使用已识别的字符串连接。否则,当 java.lang.invoke.* 机制需要字符串连接才能工作时,就会发生循环性,而字符串连接又需要 java.lang.invoke.* 机制。这种豁免可能会限制从此功能中观察到的性能改进,因为许多 java.base 类将无法使用它。我们认为这是一个可以接受的缺点,VM的优化编译器应该涵盖这一点。
18.6. 优化字符串操作 Soundex 算法的最后一步是对短结果补零和截短长结果。最佳的做法是什么? 这是目前在 soundex/stage2/soundex2c.py 中的做法: digits3 = re.sub('9', '', digits2) while len(digits3) < 4: digits3 += "0" return digit
我正在为MasterMind写一个求解器,其中我必须接受一个猜测和一个答案,并返回一些黑白钉子的数量表示,其中一个黑色钉子代表正确点的正确颜色,一个白色钉子代表不正确点的正确颜色。我必须运行这段代码大约200万次迭代,所以它需要尽可能快。目前最大的时间下沉是拆分和索引调用,但我不知道如何删除它们。关于如何在保持其功能的同时使代码运行得更快,有什么想法吗? 以确保清晰度。我的输入是用空格分隔的四种颜
最大字符串为512M,但是大字符串非常不建议。
问题 你想在字节字符串上执行普通的文本操作(比如移除,搜索和替换)。 解决方案 字节字符串同样也支持大部分和文本字符串一样的内置操作。比如: >>> data = b'Hello World' >>> data[0:5] b'Hello' >>> data.startswith(b'Hello') True >>> data.split() [b'Hello', b'World'] >>> dat
前言 忙活了一个礼拜,终于等到周末,可以空下来写点东西。 之前已经完成《数值运算》和《布尔运算》,这次轮到介绍字符串操作 。咱们先得弄明白两个内容: 什么是字符串? 对字符串有哪些操作? 下面是"在线新华字典"的解释: 字符串:简称“串”。有限字符的序列。数据元素为字符的线性表,是一种数据的逻辑结构。在计算机中可有不同的存储结构。在串上可进行求子串、插入字符、删除字符、置换字符等运算。 而字符呢?
字符串操作 函数 char * rt_strstr (const char *s1, const char *s2) 判断字符串 rt_uint32_t rt_strcasecmp (const char *a, const char *b) 忽略大小写比较字符串 char * rt_strncpy (char *dst, const char *src, rt_ubase_