为什么Java API会使用int,何时short甚至byte是足够的?
示例:DAY_OF_WEEK类中的字段Calendar使用int.
如果差异太小,那么为什么存在这些数据类型(short,int)?
担心我的网络应用程序的性能,我想知道哪个"if/else"或switch语句在性能方面更好?
我试过谷歌这个,但没有运气.
我有一个非常大的转变,有些情况显然比其他情况更常见.
因此,我想知道订单是否真的保持不变,"上"案例在"较低"之前进行测试,因此评估得更快.
我想保留我的订单,但如果它伤害速度,那么重新排序分支将是一个好主意.
例如:
switch (mark) {
case Ion.NULL:
return null;
case Ion.BOOLEAN:
return readBoolean();
case Ion.BYTE:
return readByte();
case Ion.CHAR:
return readChar();
case Ion.SHORT:
return readShort();
case Ion.INT:
return readInt();
case Ion.LONG:
return readLong();
case Ion.FLOAT:
return readFloat();
case Ion.DOUBLE:
return readDouble();
case Ion.STRING:
return readString();
case Ion.BOOLEAN_ARRAY:
return readBooleans();
case Ion.BYTE_ARRAY:
return readBytes();
case Ion.CHAR_ARRAY:
return readChars();
case Ion.SHORT_ARRAY:
return readShorts();
case Ion.INT_ARRAY:
return readInts();
case Ion.LONG_ARRAY:
return readLongs();
case Ion.FLOAT_ARRAY:
return readFloats(); …Run Code Online (Sandbox Code Playgroud) HashMap本质上具有O(1)性能,而开关状态可以具有O(1)或O(log(n)),具体取决于编译器是使用tableswitch还是查找开关.
可以理解的是,如果switch语句是这样编写的,
switch (int) {
case 1:
case 2:
case 3:
case 4:
default:
}
Run Code Online (Sandbox Code Playgroud)
那么它将使用一个tableswitch,并且显然比标准的HashMap具有性能优势.但是如果switch语句稀疏怎么办?这将是我要比较的两个例子:
HashMap<Integer, String> example = new HashMap<Integer, String>() {{
put(1, "a");
put(10, "b");
put(100, "c");
put(1000, "d");
}};
Run Code Online (Sandbox Code Playgroud)
.
switch (int) {
case 1:
return "a";
case 10:
return "b";
case 100:
return "c";
case 1000:
return "d";
default:
return null;
}
Run Code Online (Sandbox Code Playgroud)
什么会提供更多的吞吐量,lookupswitch或HashMap?HashMap的开销是否能够尽早为lookupswitch提供优势,但随着案例/条目数量的增加最终逐渐减少?
编辑:我尝试了一些使用JMH的基准测试,这里是我的结果和使用的代码.https://gist.github.com/mooman219/bebbdc047889c7cfe612 正如你们提到的,lookupswitch语句的表现优于HashTable.我仍然想知道为什么.
我有一段代码与a)我用b代替纯粹的易读性...
一个)
if ( WORD[ INDEX ] == 'A' ) branch = BRANCH.A;
/* B through to Y */
if ( WORD[ INDEX ] == 'Z' ) branch = BRANCH.Z;
Run Code Online (Sandbox Code Playgroud)
b)
switch ( WORD[ INDEX ] ) {
case 'A' : branch = BRANCH.A; break;
/* B through to Y */
case 'Z' : branch = BRANCH.Z; break;
}
Run Code Online (Sandbox Code Playgroud)
编辑:
下面的一些答案涉及上述方法的替代方法.
我已经包含以下内容以提供其使用的上下文.
我问的问题,上面的问题,是因为增加词的经验改进的速度.
这不是生产代码,而是作为PoC快速入侵.
以下似乎是对思想实验失败的证实.
我可能需要比我目前使用的词语更大的词汇.
失败的原因是我没有考虑仍需要内存的空引用. (doh!)
public class Dictionary {
private static Dictionary ROOT;
private boolean terminus; …Run Code Online (Sandbox Code Playgroud) 我没有真正的运气,通过使用Google得到这个比较的简明答案,而不是做我自己耗时的评估,我想我会先问.
我很确定使用Enums的switch语句比if-then-else语句执行得更快,不管它是否是一个明显的区别是另一个问题.
有人可以为我解释一下吗?
感谢快速回复的人,我将在未来的项目中牢记这一点.
新的 Java 17 类型模式匹配开关在幕后如何工作?由于该功能相当新,因此这个问题不讨论它。
提醒:要使此代码在 Java 17 下运行,您需要启用预览功能
public static void test (Object o) {
System.out.println(switch(o){
case Number n -> "number " + n;
case Enum e -> "enum " + e;
case String s -> "string " + s;
default -> "other " + o;
});
}
Run Code Online (Sandbox Code Playgroud)
上面代码的反汇编版本使用javap -c:
0: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
3: aload_0
4: dup
5: invokestatic #13 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
8: pop
9: astore_1
10: iconst_0
11: istore_2
12: aload_1 …Run Code Online (Sandbox Code Playgroud) 我想做这样的事情:
int i = 0;
switch(difficulty) {
case 1: i++; break;
case 2: i--; break;
default: case 1;
}
Run Code Online (Sandbox Code Playgroud)
这样的事情可能吗?我想防止重复的代码.我知道在这个特定的例子中没有理由这样做,因为重复的代码会很小.我能想出的唯一一件事是[使用开关盒的能力下降]:
switch(difficulty) {
case 2: i--; break;
default:
case 1: i++; break;
}
Run Code Online (Sandbox Code Playgroud)
我宁愿不这样做,因为增加案例数量并在底部有默认值会更有意义.
但是我想知道,如果我这样做,它会搞砸引擎盖下的goto语句吗?特别是,不需要更长的时间来决定使用哪个goto语句,因为数字或乱序?订单在switch语句中是否重要?想象一下,所有案例都有相同的被调用几率,如果你以随机顺序而不是线性顺序将它们放在一起会有意义吗?
[编辑:对于我关于效率的问题,我发现:交换语句的顺序是否重要,简短的答案是否:交换机案例顺序是否会影响速度? Java的交换机是如何工作的?
java ×8
if-statement ×3
performance ×2
comparison ×1
enums ×1
hashmap ×1
java-api ×1
optimization ×1
types ×1