-
Notifications
You must be signed in to change notification settings - Fork 539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Poor unit test performance using py_test rule #311
Comments
Hey @cwaeland, thanks for the detail you've put in here. Unfortunately, I don't have any immediate advice. I've experienced slowness in |
I am using Bazel for a Python-only codebase that is fairly small, and I see large build times (not only tests, just building is slow). Right now it takes about 10 minutes to do a full build on CI, while there is only about 10-15 Python packages. For comparison, I am able to perform a full build on another repository with only Java code in about 4 minutes (the codebase is slightly larger). Again, I am only counting build time, not test time. I don't have any precise figure, but I had the impression that it is related to the number and size of external dependencies. In particular, at some point, building the runfiles tree was taking forever. I would be very interested in understanding better the performance bottlenecks in Python… |
This issue has been automatically marked as stale because it has not had any activity for 180 days. It will be closed if no further activity occurs in 30 days. |
Hi there, we are using python 3.8 with bazel, and we have the same experience that py_test is really slow, compared with native python run, it is slower 3x at least. Any idea or suggestions for this? |
@thundergolfer any updates? |
As mentioned in the OP, this is probably a result of running tests in parallel. Some test suites, e.g. for Django, will create a database during setup. When you only invoke pytest once for the entire test suite, that cost is only paid once. If, like Bazel, you invoke pytest once per test, then all the setup, like creating a database, is multiplied by the number of tests. Could that explain the slowdown you're seeing? |
@RJPercival not in my case, because i run all tests in a service as 1 bazel test (something i didn't get around to fixing yet) and all the services are started in my CI pipeline before the build/test stage entirely (something i don't even know how to fix, because i haven't figured out how to run integration tests in bazel) |
I wonder if #1653 is related? Shall we close this issue in favour of the newer one? |
@aignas i am not using a hermetic toolchain and i appear to experience the issue anyway. i can benchmark to know for sure, if that helps |
@aignas the poor performance occurs even without using a hermetic toolchain. However, a hermetic toolchain would worsen it. |
I think the thing to do is rule out "lots of files in runfiles" as the culprit (or otherwise isolate that from performance analysis). It's easy to end up needing thousands of files after adding a few third party dependencies, which basically re-creates the situation with the hermetic runtimes -- lots of files need to be materialized in the runfiles. There's a couple known issues in Bazel that (1) this is a lot of duplicated work (the runtime and external deps are the same files for each target) and (2) macs in particular are harder hit by the cost of creating thousands of runfiles for some mac-specific reason. |
FYI: I was told that the 7.2 release of Bazel contained some performance improvements to sandboxing, which should help with the overhead of creating files. There's also a flag that might make things faster: |
I'm in the process of switching our rather large Python codebase over to using Bazel and have just finished getting our entire unit test suite to run using Bazel. Our tests are written using
unittest
and we leveraged pytest as our test runner. Typically a full run of the test suite (~6000 tests) would take around 10 minutes. However, with Bazel I'm now observing run times of about 40 minutes. Of course, once things are cached it is super fast.I knew to expect some overhead but I haven't seen anything like this with other Bazel projects I've worked on.
I went ahead and collected some timings/profile information using the
analyize-profile
option that Bazel has for subsets of our unit tests.bazel clean
was run before each timing run.First for our web package:
./bazel test tests/python/web/...
. This consist of 70 test targets. Profile information:So since this
listing_check_ins_test
(which is actually a slow test) seems to be the critical path I tried running it on its own:It seems noteworthy that when run by itself it's 3x faster.
At this point I wanted to compare to pytest.
When testing the web package using pytest we see the following result:
216 passed in 96.19 seconds
When running the single slow test with pytest:
11 passed in 32.79 seconds
.Interestingly when running the executable that Bazel produces directly (
./listing_check_ins_test
) I observe a similar time to that of pytest.Ultimately Bazel profiling seems to indicate:
Any advice on how to continue to investigate this further would be appreciated.
The text was updated successfully, but these errors were encountered: