^ in the above code, the solve function internally uses Rayon for speeding up the calculation. However, when actually running this code in Python, it runs super slow. Even though the correct number of threads are spawned and CPUs are occupied.
I tried to run the solve method in pure Rust, it runs fast as expected. I tried to wrap the running code inside the with_gil block, but it runs equally slow. I also tried to protect the game object with mutex, it didn't help either.
I ran the same code using pure rust, it takes 38s to run 100 iteration of the CFR algorithm. When running using Python, it's almost 100 times slower:
something like this:
start_time = time.time()
result = game_manager.solve_game(100, 0.3)
end_time = time.time()
I don’t recall off the top of my head how Rust+Python projects are built and configured, but is it possible to forget configuring it to release mode (i.e. with optimizations turned on) in the process?
Edit: Looking this up, I’m learning, it might depend on the way you’re doing the integration of Rust code into Python. For example using maturin, it seems you’d need to explicitly pass a -r or --release argument to the maturin build or maturin develop commands.
I’m not sure, but if I had to guess… perhaps the solver relies heavily on inlining + loop unrolling + automatic usage of SIMD by the optimizer in its core loop, in such a case 100x improvement is not out of the question.
By the way, the GIL is irrelevant to how fast the Rust code runs; however, unlocking the GIL might allow more python code to run in parallel to the solver … I suppose this may or may not be relevant to keep GUIs up to date, or if you otherwise make use of any of python’s multi-threading features.
Anyways, if you wanted to try that, you can add a py: Python<'_> argument to your function (doesn’t change the python signature) and then do the solve inside of a py.allow_threads(|| …) call. See also this page.