Parsing a few hundreds files using my grammar using a plain
for @files -> $file {
my $input = $file.IO.slurp;
my $output = parse-and-convert($input);
$out-dir.IO.add($file ~ '.out').spurt: $output;
}
loop is relatively slow and takes ~20 seconds on my machine, so I've decided to speed this up by doing this instead:
my @promises;
for @files -> $file {
my $input = $file.IO.slurp;
@promises.append: start parse-and-convert($input);
}
for await @promises -> $output {
$out-dir.IO.add($file ~ '.out').spurt: $output;
}
This works (at least in my real code, i.e. modulo any typos in this illustrative example), but the speedup is much less than I hoped for: it now takes ~11s, i.e. I've gained a factor of only two. This is appreciable, of course, but it looks like there is a lot of contention because the program uses less than 6 CPUs (on a system with 16 of them) and quite a bit of overhead (because I don't get a factor of 6 speedup neither).
I've confirmed (by inserting some say now - INIT.now
) that almost all the running time is really spent inside await
, as expected, but I have no idea how could I debug/profile it further. I'm doing this under Linux, so I could use perf, but I am not sure how would it help me at Raku level.
Would there be some simple way to improve the degree of parallelism here?
Edit: Just to make it clear, I can live with 20s (well, 30s by now, as I've added more things) running time, I'm really mostly curious about whether the degree of parallelism could be somehow improved here, without rewriting the grammar (unless there is something very specific, like e.g. use of dynamic variables, that should be avoided when using multiple threads).