并发的狗粮

楽土

我在 Raku 项目中使用 zef --verbose test . 在 Makefile 中用 F2 键触发运行测试。虽然 zef 很好,但它也很慢,还不是很快。如果它能并行运行测试,可能会更快一些。因为我把测试分成了不同的文件,所以并发运行它们并不难。最大的障碍是收集所有的输出,并在不混行的情况下显示它们。有了 Shell::Piping,这确实非常容易。

constant NL = $?NL;
my &RED = { "\e[31m$_\e[0m" };
my &BOLD = { "\e[1m$_\e[0m" };

&RED = &BOLD = { $_ } unless $*OUT.t;

sub run-test(IO::Path $file where { .e & .f }) {
    my @out;
    my @err;
    my $failed;
    px«raku -Ilib $file» |» @out :stderr(@err) :done({$failed = .exitcodes.so});

    („Testing: {$file}“.&BOLD, @out, @err».&RED).flat.join(NL);
}

我向 raku 出壳,让它运行单个测试文件。STDOUT 和 STDERR 的流最终会被写入 Array。然后,这些流按照正确的顺序合并,并添加一些颜色。现在我必须得到文件列表,并并行运行测试。

.put for dir(‚t/‘).grep(*.extension eq ‚t‘).sort.hyper(:batch(1), :degree(12)).map(*.&run-test);

由于 .hyper 的魔力,输出是以正确的顺序放出的。用一个 raku 进程,测试需要 11.3s。用 12 个线程的话,就降到了 3s。我将立即在 vim 中把绑定改为 F2!。

整个脚本可以在这里找到,Shell::Piping这里找到。后者将很快登陆生态系统。

comments powered by Disqus