Performance degression on Upgrade from 1.10.19 to current 3.6.28
See original GitHub issueHello Mockito team,
Quick stats: Java 11 Mockito 1.10.19 to 3.6.28 1:30 minutes to 9 minutes
in our company we still use Mockito 1.10.19, which includes cglib.
In our unit tests we kind of have our own testing framework that encapsulates e.g. the persistence layer. And in the actual unit tests we don’t need to actual mock. With that in mind the framework is already a lot of preparations which is not be needed for every test. We use mainly mock creations and methodinterceptors as far as I can tell.
At the moment an upgrade wouldn’t make sense for us. As the duration of the tests would increase from 1 minute and 30 sec to roughly 9 minutes so 6 times worse.
I had a first look what’s taking so long. In my opinion there are two things:
1.
org/mockito/internal/creation/bytebuddy/MockMethodInterceptor.java:55
In return doIntercept(mock, invokedMethod, arguments, realMethod, new LocationImpl())
you construct and initliaise a new LocationImpl, which is quite expensive according to my CPU profiling (IntelliJ profiler)
After replacing that part with a dummy Locationimpl, which does nothing and is a static instance I got down to something like 5 min from 9.
I dunno exactly what the stacktrace information is being used for. It seems in 1.x this is not being done.
- the mock creation itself
Here it seems to me that bytebuddy is doing way more complicated and of course as I understand more feature rich type traversal, which is making things go slow, but on the other hand work .
Here I’m wondering, if there is a global config switch to do just simple mocking like cglib has done previously.
I know that in general the architecture has changed significantly from version 1 to 2/3 to have features/bugfixes that were impossible beforehand. So I’m not sure what performance wise is feasible without going completely a different way.
Thank you in advance for your help 😉
Issue Analytics
- State:
- Created 3 years ago
- Comments:26 (14 by maintainers)
Top GitHub Comments
I am not sure which JVMs ship the required classes, as it might be that OpenJDK no longer includes them. I do see some references in OpenJDK8 for example: http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/sun/misc/SharedSecrets.java You might have to test a couple of JVMs to see which one would be compatible.
You can use
MockitoFramework.addListener
to attach aMockCreationListener
where you could implement a simple static counter for example.Thank you for the great support. I don’t have any performance issues anymore. Yet I’m not sure yet what’s causing it. Could be some independent changes of a colleague. I don’t know.
Yet the performance is at least very similar to 1.x performance 😉 😃
If I find the cause I will keep you posted.