java性能优化方案8——使用EnumSet或EnumMap

8、使用EnumSet或EnumMap
在某些情况下,比如在使用配置map时,我们可能会预先知道保存在map中键值。如果这个键值非常小,我们就应该考虑使用 EnumSet 或 EnumMap,而并非使用我们常用的 HashSet 或 HashMap。下面的代码给出了很清楚的解释:
private transient Object[] vals;

public V put(K key, V value) {

// ...
int index = key.ordinal();
vals[index] = maskNull(value);
// ...

}
上段代码的关键实现在于,我们用数组代替了哈希表。尤其是向map中插入新值时,所要做的仅仅是获得一个由编译器为每个枚举类型生成的常量序列号。如果有一个全局的map配置(例如只有一个实例),在增加访问速度的压力下,EnumMap 会获得比 HashMap 更加杰出的表现。原因在于 EnumMap 使用的堆内存比 HashMap 要少 一位(bit),而且 HashMap 要在每个键值上都要调用 hashCode() 方法和 equals() 方法。
小结
Enum 和 EnumMap 是亲密的小伙伴。在我们用到类似枚举(enum-like)结构的键值时,就应该考虑将这些键值用声明为枚举类型,并将之作为 EnumMap 键。

时间: 2024-09-11 02:33:42

java性能优化方案8——使用EnumSet或EnumMap的相关文章

java性能优化方案5——使用原始类型和栈

5.使用原始类型和栈之前介绍了来自 jOOQ的例子中使用了大量的泛型,导致的结果是使用了 byte. short. int 和 long 的包装类.但至少泛型在Java 10或者Valhalla项目中被专门化之前,不应该成为代码的限制.因为可以通过下面的方法来进行替换://存储在堆上Integer i = 817598;--如果这样写的话:// 存储在栈上int i = 817598;在使用数组时情况可能会变得更加糟糕://在堆上生成了三个对象Integer[] i = { 1337, 4242

java性能优化方案10——考虑使用set而并非单个元素

10.考虑使用set而并非单个元素最后,还有一种情况可以适用于所有语言而并非仅仅同Java有关.除此以外,我们以前研究的N.O.P.E. 分支也会对了解从 O(N3) 到 O(n log n)有所帮助.不幸的是,很多程序员的用简单的.本地算法来考虑问题.他们习惯按部就班地解决问题.这是命令式(imperative)的"是/或"形式的函数式编程风格.这种编程风格在由纯粹命令式编程向面对象式编程向函数式编程转换时,很容易将"更大的场景(bigger picture)"模

java性能优化方案9——优化自定义hasCode()方法和equals()方法

9.优化自定义hasCode()方法和equals()方法在不能使用EnumMap的情况下,至少也要优化 hashCode() 和 equals() 方法.一个好的 hashCode() 方法是很有必要的,因为它能防止对高开销 equals() 方法多余的调用.在每个类的继承结构中,需要容易接受的简单对象.让我们看一下jOOQ的 org.jooq.Table 是如何实现的?最简单.快速的 hashCode() 实现方法如下:// AbstractTable一个通用Table的基础实现: @Ove

java性能优化方案3——不要使用iterator()方法

3.不要使用iterator()方法这条建议不适用于一般的场合,仅适用于在 N.O.P.E 分支深处的场景.尽管如此也应该有所了解.Java 5格式的循环写法非常的方便,以至于我们可以忘记内部的循环方法,比如:for (String value : strings) { // Do something useful here }当每次代码运行到这个循环时,如果 strings 变量是一个 Iterable 的话,代码将会自动创建一个Iterator 的实例.如果使用的是 ArrayList 的话

java性能优化方案6——避免递归

6.避免递归现在,类似Scala这样的函数式编程语言都鼓励使用递归.因为递归通常意味着能分解到单独个体优化的尾递归(tail-recursing).如果你使用的编程语言能够支持那是再好不过.不过即使如此,也要注意对算法的细微调整将会使尾递归变为普通递归.希望编译器能自动探测到这一点,否则本来我们将为只需使用几个本地变量就能搞定的事情而白白浪费大量的堆栈框架(stack frames).小结这节中没什么好说的,除了在 N.O.P.E 分支尽量使用迭代来代替递归.

java性能优化方案2——避免使用正则表达式

2.避免使用正则表达式正则表达式给人的印象是快捷简便.但是在 N.O.P.E 分支中使用正则表达式将是最糟糕的决定.如果万不得已非要在计算密集型代码中使用正则表达式的话,至少要将 Pattern 缓存下来,避免反复编译Pattern.static final Pattern HEAVY_REGEX = Pattern.compile("(((X)*Y)*Z)*"); 如果仅使用到了如下这样简单的正则表达式的话:1 String[] parts = ipAddress.split(&qu

java性能优化方案1——使用StringBuilder

1.使用StringBuilderStingBuilder 应该是在我们的Java代码中默认使用的,应该避免使用 + 操作符.或许你会对 StringBuilder 的语法糖(syntax sugar)持有不同意见,比如:1 String x = "a" + args.length + "b";将会被编译为: 0 new java.lang.StringBuilder [16] 3 dup 4 ldc [18] 6 invokespecial java.lang.S

java性能优化方案——使用entrySet()

7.使用entrySet()当我们想遍历一个用键值对形式保存的 Map 时,必须要为下面的代码找到一个很好的理由:for (K key : map.keySet()) { V value : map.get(key); }更不用说下面的写法:for (Entry entry : map.entrySet()) { K key = entry.getKey(); V value = entry.getValue(); }在我们使用 N.O.P.E. 分支应该慎用map.因为很多看似时间复杂度为 O

java性能优化方案4——不要调用高开销方法

4.不要调用高开销方法有些方法的开销很大.以 N.O.P.E 分支为例,我们没有提到叶子的相关方法,不过这个可以有.假设我们的JDBC驱动需要排除万难去计算 ResultSet.wasNull() 方法的返回值.我们自己实现的SQL框架可能像下面这样:if (type == Integer.class) { result = (T) wasNull(rs, Integer.valueOf(rs.getInt(index))); } // And then...static final T was