Skip to content
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

sameBeanAs being EXTREMELY slow since 0.10 version #24

Open
rtretyak opened this issue Jun 1, 2017 · 2 comments
Open

sameBeanAs being EXTREMELY slow since 0.10 version #24

rtretyak opened this issue Jun 1, 2017 · 2 comments

Comments

@rtretyak
Copy link

rtretyak commented Jun 1, 2017

Hello. First, thanks for this outstanding tool, I find it one of the best out there for comparing complex objects.
Now the issue(specific for v.0.10 and 0.11):
the sameBeanAs matcher takes VERY long time to execute. In some cases it took like 1-2 seconds for me (which is slow) but I was ready to bear with it in exchange for nice error messages and ability to ignore fields, but today I found a single operation take 20 seconds (!!!).
The setup I use: Groovy language, Spock framework, shazam version 0.11
See screenshot: image
How I did that measuring: basically just

def now = System.currentTimeMillis()  
//single sameBeanAs assertion  
println("sameBeanAs took: ${System.currentTimeMillis() - now}millis")

What I compare: just couple custom domain classes that represent jsons, not too heavy (not heavy at all, I would say rather simple)
Important notes: The 20 second issue reproduces in avg once per ~4 runs, not always, but even when it is not 20s, it takes about 1-2 seconds which is very slow too.
The issue is not reproducing in shazam v0.9 (which I rolled back too), all the operations take <10 milliseconds in absolutely equal conditions.
I would be looking into your source code when I have some free time, but it would be great if someone have some thoughts on this and could do that quicker. This issue may be a major showstopper for attracting wider auditory to this tool so I'm really concerned about getting this fixed ASAP.

@lucanaldini
Copy link
Contributor

Hello, thanks for your message.
Could you provide a code snippet that reproduces the issue?
That would help greatly trying to identify the problem.
Thanks

@rtretyak
Copy link
Author

rtretyak commented Jun 1, 2017

Ok I have something.
First of all, it appeared to be a groovy-only case. Previously I thought that this is a more general issue. Issue appears when you add any method to ANY class using Groovy's metaClass.
So this works perfect:

package example.spec

import example.Name
import spock.lang.*

import static com.shazam.shazamcrest.matcher.Matchers.*
import static spock.util.matcher.HamcrestSupport.*

class MySpec extends Specification {
    @Unroll
	def "example test"() {
        given:
            def actual = new Name(first: "foo", last: "bar")
            def expected = new Name(first: "foo", last: "bar")
        expect:
            def now = System.currentTimeMillis()
            that actual, sameBeanAs(expected)
            println("sameBeanAs took: ${System.currentTimeMillis() - now}millis")
        where: iterations << (1..3)
    }
}

But now add this code right after 'given' and before 'def actual'(it actually doesn't matter where to use metaclass, it can even be not in the test class but somewhere else):

Map.metaClass.anyNewMethod = { /*do anything, it doesn't matter*/ }

And now the execution time bumps up to 3-20 seconds per each assertion. It doesn't have to be Map, it can basically be any class (String, Integer etc.), doesn't matter.
In debug I see that the amount of 'circularReferenceTypes' is doubled when metaclass is used.
So this issue messes up with Groovy language a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants