Assuming it is faster, one reason could be that the macro can do something like embedding the corresponding pyc file instead of a py file. I don't know how it actually works, but this is a possibility.
To make sure your original measurements of Rust taking 187ms and Python taking 203ms are accurate and not just noise, you should run the same Measure-Command test several thousand times and look at the statistics.
I don't know whether Measure-Command will run the command several times and take an average for you, but if not I've heard great things about using hyperfine to measure performance for command-line programs.
Thanks, I used hyperfine for loops of 1_000, 10_000, 100_000 and 1_000_000 and looks calling Python from Rust is slightly faster than Python directly, but whay?
It's impossible to say for certain without profiling both, but it's possible that the python interpreter has to spend more time on things like filesystem calls and file I/O.
Maybe it's the difference of having to read the cv.py file, especially when stuff like virus scanners get involved, versus having that source embedded in the rust executable.
My two cents is that the Python interpreter needs to compile the high-level Python code to bytecode each time it runs (which takes time).
But that Rust already compiles the included Python script to bytecode when it is build, so when actually running the Rust script you're saving time by not needing to compile your Python script to bytecode anymore.
Not sure though.
Maybe @kngwyu knows more about this (contributer of Pyo3).