-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Performance degradation after migration to mockito 2 #1797
Comments
Could you do a performance trace with https://visualvm.github.io/ and analyze where we lose the most amount of time? |
And it is not totally unexpected the time has increased, as the ByteBuddyMockmaker actually follow the Java specification, which the CGLibMockmaker did not. However, such a large performance regression is unexpected. |
It looks like most of the time (about 1 minute) is spent in org.mockito.internal.runners.DefaultInternalRunner$1$1.evaluate() |
That makes sense, as that is the overall wrapping runner. I guess we need a little bit more fine-grained data. E.g. if you ignore the infrastructure related to JUnit, what part of the Mockito internal system is most used. Maybe to ease the debugging, could you post a screenshot of the flamechart of the methods that are most often called? |
Hope this helps See attached full profiler result |
Thank you for the flamechart. The work in ByteBuddy definitely introduces a large amount of overhead for the simple test. However, this is not totally unexpected for the creation of 30000 mocks. Assigning @raphw for now who might have some more thoughts on how to speed up ByteBuddy, but in general I think trying to limit the amount of mocks you create in your test suite is a better solution. Do you have any numbers on how many mocks are getting created in your own test suite? |
Mock creation is more expensive in Byte Buddy compared to cglib since Byte Buddy processes generic data to get bridges right. This alone takes a lot of additional time. Normally, this is not sn issue since nobody would mock 30k classes in a two second test. The Byte Buddy based mocks are more performant, as a matter of fact and would amortize their costs in a long running applications but this rarely plays a role in test suites, especially not in one like yours. Are you sure this is the performance isdue you are experiencing? Does this also degrade performance of an actual test suite? There might be other reasons that your actual tests became slower. If you mock 200 classes that should not take more than 20 milliseconds even on a cold VM. Unless you are doing something particular, this change should not normally impact you. |
@TimvdLippe Real suite I am trying to migrate to Mockito 2 have the following stats runtime with Mockito 1 ~ 17 sec So in total it is a ~ 9k of mocks causing degradation ~5 times Perhaps the provided test example does not highlight the whole issue, but hopefully the profiler snapshots do, since runtime of unit tests becomes a blocker for migration Let me know if I can provide anything else to help resolve the issue |
I think that is the trade-off we accepted. We opted for a more correct Mockmaker in exchange for a small loss of performance on initial mock creation (which the CGLibMockmaker did). However, if your test has a lot of mock creation without a lot of mock interaction, this cost will trump any other cost in your unit test. At this point, I think the best way forward is to limit the amount of mocks you create in your unit tests. Creating 9000 mocks is a lot and I don't think any times of performance improvements on the side of ByteBuddy is ever going to offset the amount of pressure being put on the dynamic class generation. If you are still able to reproduce this issue with way fewer mocks, then there is definitely a performance regression we should fix. But currently I would say this is WAI and expected to be more computationally expensive, given the amount of mocks. |
I see a huge performance increase (25ms vs 430ms in a very simple test case with just one mock) when instantiating mocks inline Is this expected or is it wrong to create mocks inline? Some further details here https://stackoverflow.com/questions/59390997/why-do-i-see-a-performance-boost-when-creating-mockito-mocks-inline |
Might this be a Kotlin-related thing? This should really not be the case if you instantiate the same amount of mocks. Mockito - like any Java program - is not aware of the caller of its methods, therefore it should not really make a difference. Could you run both scenarios with a profiler attached and see where the additional time is spent relatively? |
Well, turns out the "performance increase" was just android studio being misleading with test execution times. I used JProfiler and saw that both inlining the method call and doing it in the setup method leads to a call to The only difference is where in the stack trace said call is performed, so I'm assuming android studio only starts counting after a certain point, which leads to the very low execution times. |
Can we use mockito 3.2.4 instead (https://search.maven.org/artifact/org.mockito/mockito-core)? Are there any performan ce issues? |
sorry to revive this old thread 13.4k tests takes more than 2 minutes vs 22 seconds with old Mockito version |
Hey,
I am facing severe test suite execution performance degradation during Mockito migration
from version 1.10.19 to 2.28.2
Whole migrated test suite (about 12k tests) run takes ~18 seconds while after migration it took around 2 minutes. I have checked previous performance related tickets, but those are supposed to be resolved in version I use for migration.
Initial setup
java version: 1.8.0_112
junit version: 4.12
mockito version: 1.10.19
Migrated setup
java version: 1.8.0_112
junit version: 4.12
mockito version: 2.28.2
30,000 mocks
Test Results (in milliseconds) on my laptop (8 Core, 16 Gb RAM)
It seems to be related to the way method mocking is done, since blank mock creation shows similar results for both mockito versions.
See two small test projects (for mockito verstion 1 and version 2) attached
perf_test.zip
The text was updated successfully, but these errors were encountered: