gpt4 book ai didi

kotlin - 为什么标准迭代器比Kotlin中的序列要快?

转载 作者:行者123 更新时间:2023-12-02 13:04:35 24 4
gpt4 key购买 nike

我是序列的新手,所以我可能做过(或多或少)非常错误的事情,但是我有一个疑问:
我写了两个函数:

fun isPrimeNumber1(number: Int): Boolean {
if (number <= 1) return false
for (divider in 2 .. number / 2) {
if ( number % divider == 0 ) return false
}
return true
}
fun isPrimeNumber2(number: Int): Boolean {
if (number <= 1) return false
return !(2 .. number / 2).asSequence().map { it }.any { number % it == 0 }
}
现在,我正在运行一个用 kotest编写的测试,其中两个函数都将 Int.MAX_VALUE接收为 number
class MyTestPrime : FunSpec({
context("Prime numbers") {
test("Should return true if number is prime (1st fun)") {
isPrimeNumber1(Int.MAX_VALUE) shouldBe true
}
test("Should return true if number is prime (2nd fun)") {
isPrimeNumber2(Int.MAX_VALUE) shouldBe true
}
}
})
isPrimeNumber1()函数的执行时间约为3.5秒,而第二个函数 isPrimeNumber2()的执行时间约为8.5秒。
为什么呢?我是否缺少有关序列的信息?还是我的代码以正确但非常不理想的方式实现了它的目的?

最佳答案

可以预料的。具有序列的变量创建一个Iterator对象,并为每个元素调用.hasNext().next()函数。
由于Iterator适用于对象而不适用于基元,因此所有int都会通过Integer::valueOf调用进行装箱。 (注意:.map { it }步骤是多余的)。
我通过IntelliJ Idea中的Java Flight Recorder运行了这两个函数,并且可以看到,与另一个变体相比,序列变体导致更多的函数调用。
isPrimeNumber1:
isPrimeNumber1
isPrimeNumber2:
isPrimeNumber2
如您所见,isPrimeNumber2变体导致更多函数在后台被调用,因此受到其开销的影响。
检查它的另一种方法是将两个函数的字节码反编译为Java。它可以让您更好地了解引擎盖下发生的事情。这是两个反编译的函数(再次使用IntelliJ):

private static final boolean isPrimeNumber1(int number) {
if (number <= 1) {
return false;
} else {
int divider = 2;
int var2 = number / 2;
if (divider <= var2) {
while (true) {
if (number % divider == 0) {
return false;
}

if (divider == var2) {
break;
}

++divider;
}
}

return true;
}
}

private static final boolean isPrimeNumber2(int number) {
if (number <= 1) {
return false;
} else {
byte var1 = 2;
Sequence $this$any$iv =
SequencesKt.map(
CollectionsKt.asSequence((Iterable) (new IntRange(var1, number / 2))),
(Function1) null.INSTANCE);
int $i$f$any = false;
Iterator var3 = $this$any$iv.iterator();

boolean var10000;
while (true) {
if (var3.hasNext()) {
Object element$iv = var3.next();
int it = ((Number) element$iv).intValue();
int var6 = false;
if (number % it != 0) {
continue;
}

var10000 = true;
break;
}

var10000 = false;
break;
}

return !var10000;
}
}
最后说明:如其他人所述,要获得有意义的性能评估,您需要使用 jmh之类的工具。但是,根据经验,较简单的语言构造(例如,序列上的常规for / while循环)由于其提供的抽象级别较低而倾向于具有较少的开销。

关于kotlin - 为什么标准迭代器比Kotlin中的序列要快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64413369/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com