openlang

try vs catch unreachable in a hot loop, numbers make no sense

I'm timing try parseLine(line) against parseLine(line) catch unreachable over ~2M generated ts,level,bytes lines, summing the bytes. Built with -Doptimize=ReleaseFast.

The try run reports a few hundred microseconds and prints an error name instead of a total. The catch unreachable run takes tens of ms, and its total is different. ReleaseSafe and Debug panic on the second one. I added a corrupt line every 5000 lines to "make it realistic". With --bad-every 0 things look saner, but I don't get why it matters this much.

The two loops:

const e = try parse.parseLine(line);
total += e.bytes;
// vs
const e = parse.parseLine(line) catch unreachable;
total += e.bytes;

My guesses were error return traces or inlining. I haven't looked at the assembly yet. Input generation is already outside the timer. (splitScalar showed up around 0.12, I think, nvm if that's off.)

So what is this actually measuring? Thanks for any pointers.

The conversation continues 2

Follow the reasoning
  1. Permalink

    You're not comparing two ways of handling the same work. The try run is bailing out at the first bad line. A few hundred µs for 2M lines means it barely got started, and the error name you see is the one from that early return. If your generator does i % 5000 == 0, line 0 is already corrupt, so it dies straight away.

    The catch unreachable run is a different problem. In ReleaseFast that's undefined behaviour on the first bad line, so the optimiser can do whatever it likes. That's why the total is off. Debug and ReleaseSafe panic because they actually check. The tens of ms isn't a number you can trust either, since the compiler may have folded the loop into something odd.

    I'd bench it with zero bad lines first, then bad lines handled with catch continue or a counter. Compare those. Print how many lines were actually parsed alongside the total, so you know the loop ran to the end.

    Honestly it looks like a codegen quirk to me, so I'd check your Zig version too. Which build are you on?

Other sides of the same question

  1. simple loops very slow, gfortran, 200000 x 64 array

    Small calibration tool, code below. Output is right but it is too slow. detrend+clip takes several seconds, rms also slower t…

    Replies 2Latest activity fortran
  2. running_mean slow, time goes to memmove not arithmetic

    Smoothing sensor data. Array is readings(nstation, ntime), station first, because the data file is laid out so and other tool…

    Replies 1Latest activity fortran
  3. Which build time are you quoting?

    Every crate-splitting thread ends with someone posting a single build time. There are two, and they move in different directi…

    Replies 2Latest activity rust