这是小小的试验性库包,建立在 "Java coroutines"(又称虚拟线程)之上的生成器:
一个将0到1000000的数字相加的生成器,java实现的运行时间大约是python实现的100倍
package io.avery.util.concurrent;
import java.time.Duration; import java.time.Instant; import java.util.concurrent.Executors;
public class Main { public static void main(String[] args) throws InterruptedException { // Try changing this to Executors.newSingleThreadExecutor() try (var exec = Executors.newVirtualThreadPerTaskExecutor(); var gen = new Generator<>(exec, (Channel<Void, Integer> chan) -> { for (int i = 0; i < 1000000; i++) chan.yield(i); }) ) { Instant start = Instant.now(); long sum = 0; for (Integer n; (n = gen.next(null)) != null;) { sum += n; } Instant end = Instant.now(); System.out.printf("Sum: %d, Elapsed: %s%n", sum, Duration.between(start, end)); } } }
|
不幸的是,粗略的性能测试表明,上下文切换的开销是不可接受的。
我尝试了几个替代java实现的方法,以确认缓慢的来源。将PingPong的实现替换为自旋环路的实现(_unusedSpinPingPong),结果是性能与python的实现相当,但当然是浪费了CPU。用另一个黑客实现(_unusedNosyncPingPong)替换PingPong实现,试图剥离大部分同步开销,但保留了上下文切换开销,并没有明显改善性能。
其他:Vert.x 虚拟线程孵化器