Groovy中的循环性能

介绍

2018年Code Advent挑战赛中,我解决了Groovy中的所有难题。 显而易见,选择良好的数据结构对于获得高性能的解决方案最为重要。 但是,至少在使用Groovy时,我们迭代这些结构的方式也非常重要。

衡量绩效

我想测量求和一些数字所需的时间。 为了测试循环的性能,我准备了一个小函数,将一些数字简单地求和:

void printAddingTime(String message, long to, Closure<Long> adder) {
    LocalTime start = LocalTime.now()
    long sum = adder(to)
    println("$message: $sum calculated in ${Duration.between(start, LocalTime.now()).toMillis()} ms")
}

用于求和函数的伪代码如下:

for i = 1 to n
  for j = 1 to n
    sum += i * j
  end
end

循环类型

让我们以各种方式实现求和功能。

第一个循环型是使用内置(通过Groovy中)功能collectsum上集合( Range是本示例):

(1..n).collect { long i ->
  (1..n).collect { long j ->
    i * j
  }.sum()
}.sum()

each

接下来,让我们用写相同功能的each内置功能上集合( Range是本示例),然后添加结果累加器变量:

long sum = 0
(1..n).each { long i ->
    (1..n).each { long j ->
        sum += i * j
    }
}
return sum

times

现在,可以使用Groovy内置于Number的函数times来代替使用each函数:

long sum = 0
n.times { long i ->
  n.times { long j ->
    sum += (i + 1)*(j+1)
  }
}
return sum

我们必须在ij上加1 ,因为时间会生成从0n数字(不包括数字)。

Java 8附带了一个新功能–流。 流的一个示例是LongStream 。 幸运的是,它具有sum内置函数,我们可以使用:

LongStream.range(0, n).map { i ->
    LongStream.range(0, n).map { j ->
        (i + 1) * (j + 1)
    }.sum()
}.sum()

LongStream生成数字与times函数的方式相同,因此我们还必须在此处将ij1

带手动求和的

代替LongStream上的sum函数,我们可以手动将所有数字相加:

long sum = 0
LongStream.range(0, n).forEach { i ->
    LongStream.range(0, n).forEach { j ->
        sum += (i + 1) * (j + 1)
    }
}
return sum

while

当然,由于Groovy从Java继承了大部分语法,因此我们可以使用while循环:

long sum = 0
long i = 1
while(i <= n){
    long j = 1
    while(j <= n){
        sum+= i*j
        ++j
    }
    ++i
}
return sum

for

正如我们可以使用while ,我们也可以在Groovy中使用for循环:

long sum = 0
for (long i = 1; i <= n; ++i) {
    for (long j = 1; j <= n; ++j) {
        sum += i * j
    }
}
return sum

结果

我的测试在Java 1.8和Groovy 2.5.5上运行。 使用bash脚本触发了脚本loops.groovy

#!/bin/sh
for x in 10 100 1000 10000 100000; do
  echo $x
  groovy loops.groovy $x
  echo
done

值以毫秒为单位

循环n 10 100 1000 10000 100000
collect + sum 7 22 216 16244 1546822
each 12 17 118 7332 706781
times 2 10 109 8264 708684
LongStream + sum 7 17 127 7679 763341
LongStream +手动求和 18岁 35 149 6857 680804
while 8 20 103 3166 301967
for 7 10 25 359 27966

如您所见,使用内置Groovy函数进行少量迭代就足够了,但是对于大量迭代,我们应该使用whilefor循环,例如在普通的旧Java中。

给我看代码

这些示例的代码在此处提供 。 您可以在计算机上运行这些示例,并自行检查性能。

翻译自: https://www.javacodegeeks.com/2019/01/loops-performance-groovy.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值