我一直在阅读 Effective Java,3/E。
在阅读有关哈希码的部分时,(第 51 页)我注意到这本书说
31一个很好的特性是乘法可以通过移位,并有更好的表现在某些架构减法来代替:
31 * i == (i << 5) - i。现代虚拟机会自动进行这种优化。
我认为这是有道理的。我想知道当这种优化发生时,代码会变得多快。所以我写了一个简短的代码来看看这种优化的影响。
但是,似乎没有明显的差异。所以我写了更简单的代码,以检查是否发生了这种优化。
下面是我的示例代码。
fun main() {
val num = Random.nextInt()
val a = num * 30
val b = num * 31
val c = num * 32
println("$a, $b, $c")
}
Run Code Online (Sandbox Code Playgroud)
这是编译后的机器代码,来自 IntelliJ 的 Kotlin 字节码功能。
L1
LINENUMBER 5 L1
ILOAD 0
BIPUSH 30
IMUL
ISTORE 1
L2
LINENUMBER 6 L2
ILOAD 0
BIPUSH 31
IMUL
ISTORE 2
L3
LINENUMBER 7 L3 …Run Code Online (Sandbox Code Playgroud) 最近我使用Redis.Eval改进了一些代码,效果很好.事实上,这工作得太好了,但我不明白这是怎么回事.
改进的redis代码多次使用Redis.zcard来使用Redis.eval一次.代码的速度提高了100倍(在测试环境中.在实际项目中,速度提高了1000倍以上).我不知道为什么.有人可以解释一下吗?
它做了一个非常简单的任务.它需要一个字符串数组,它是存储在Redis中的ZSET的关键字,并对相应ZSET的大小求和,并返回一个整数值,即和.
为了尽可能多地消除外部变量,我建立了一个简单的测试环境,如下所示.
redis = Redis.new(host: '127.0.0.1', db: 1)
KEYS = 500.times.collect do |i| "KEY#{i}" end
KEYS.each do |key|
redis.zadd(key, 0, "DATA")
end
Run Code Online (Sandbox Code Playgroud)
在我更改代码之前,它的工作原理如下.
sum = 0
KEYS.each do |key|
sum += redis.zcard(key)
end
Run Code Online (Sandbox Code Playgroud)
然后我使用以下单行代码测试了此代码的速度.
t = Time.now; sum=0; KEYS.each do |key| sum += redis.zcard(key) end; puts(Time.now - t)
结果打印出来0.202seconds(202ms)
(请注意我根据测试环境和上面编写的代码计算时间,而不是真实环境)
在我使用Lua脚本和EVAL更改代码之后,它的工作原理如下.
script = "
local sum = 0
for index, key in pairs(KEYS) do
sum = sum + redis.call('zcard', key);
end …Run Code Online (Sandbox Code Playgroud)