Haven't tested it (or even read the article :) ), but maybe some kind of JIT optimization kicks in the 1000 element case (ie afer the "loop" ran enough times) but not in the others?
EDIT: Maybe what happened is that the 500 case made the engine conclude that the function is called frequently enough to be optimized, and the 500 run both spent a while with the slow version and spent some time optimizing it, while the 1000 case got to exclusively use the optimized version.
Just goes to show that benchmarking complex multi-stage JITs can be hard.
There are a ton of things one needs to do to make reliable microbenchmarks (make sure the functions are getting optimized, make sure they're not eliminated as dead code, etc.) and I don't think this repo does any of them.