能用PreparedStatement就不要使用Statement 推荐的方式:
PreparedStatement stmt = conn.prepareStatement(“select TD_M_ASYNCTASK WHERE LOG_ID = ?”); stmt.setString(1, “10000000085005”); stmt.executeQuery(); 不推荐的方式:
Statement stmt = conn.createStatement(); stmt.execute(“select * TL_M_ASYNCTASK_LOG WHERE LOG_ID = ‘” + logID + “’”); 两者的性能差距就是编译型语言与脚本语言的差距。 17) 与反射调用有关的性能问题
尽可能缓存Method对象,获取Method对象是反射调用最消耗性能的地方。 18) 缓存使用的性能问题 缓存的作用有两个:
- 将需要的数据搬到更近的地方。 - 缓存计算结果。
避免从缓存获取数据后,再对数据进行排序、过滤等操作。
正确的做法是,先排序好,过滤完再放进缓存,以后直接拿来用即可。 19) 并发锁带来的性能问题
- 最好是不用锁,比如用CAS机制解决并发问题。 正确的计数器写法:
private static AtomicInteger count = new AtomicInteger(); public void xxx() { ... // 业务处理 count.getAndIncrement(); // 计数器递增 } 错误的计数器写法:
private static int count = 0; public static synchronize int increment() { ... // 业务处理 return count++; // 计数器递增 } - 在读多写少的并发场景,用读写锁,不要用排它锁,如synchronize。 20) 杂项
31
- 避免频繁使用instanceof做类型判断,建议拆成多个对象,用多态调用。 - 正则表达式比较灵活,但在特定场景下性能不一定最优。
- 避免对象的反复构造,可以复用就复用,尤其是大对象的构造,是非常消耗性能的。
- 两数组对拷,记得用System.arraycopy(),不要自己写for循环,性能差距非常大。
32