The code looks good and seems to be well structured, so that I think I understand what is going on even without running it.
From my personal point of view, a clean and modifiable code is really important if you are planning to run some experiments. While the performance is certainly important as well, I think the functionality comes first and you can try to optimizer certain parts of the code later (especially after isolating the bottlenecks).