小编Che*_*eon的帖子

将 int 乘以 30、31、32 - 这些真的被编译器优化了吗?(有效的java是这么说的)

我一直在阅读 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)

java optimization compiler-optimization kotlin

5
推荐指数
1
解决办法
131
查看次数

Redis - 为什么这段代码很快?

最近我使用Redis.Eval改进了一些代码,效果很好.事实上,这工作得太好了,但我不明白这是怎么回事.

对于TL; DR

改进的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)

ruby performance lua nosql redis

3
推荐指数
1
解决办法
347
查看次数