[
https://issues.apache.org/jira/browse/LANG-1493?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Miguel Munoz updated LANG-1493:
-------------------------------
Description:
The EqualsBuilder.reflectionEquals() method is very inefficient. It reflects
through all the fields of a class every time it needs to do a comparison. A
faster approach would be to do the reflection once when the class loads, and
re-use it for each instance. This change, however, needs a different API and
couldn't be a drop-in replacement for EqualsBuilder. Instead it would need to
be a new class.
I have written a class that can do this. Performance tests show that it runs
up to 20 times faster, depending on how many fields it needs to compare before
finding a difference.
You can try the class out by going to [https://github.com/SwingGuy1024/DogTags].
The API currently works like this:
{code:java}
public class MyClass {
// fields and methods omitted for brevity
// Use reflection to implement equals() and hashCode() based on all non
transient, non static fields
private static final DogTag.Factory<MyClass> factory =
DogTag.create(MyClass.class).build();
private final DogTag<MyClass> dogTag = factory.tag(this);
@Override
public boolean equals(Object that) {
return dogTag.equals(that);
}
@Override
public int hashCode() {
return dogTag.hashCode();
}
}{code}
An alternative way to do this is to specify function pointers
{code:java}
public class MyClass2 {
private String name;
private int age;
public MyClass2(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name;}
public int getAge() { return age;}
private static final DogTag.Factory<MyClass2> factory =
DogTag.createByLambda(MyClass2.class)
.addSimple(MyClass2::getAge)
.addObject(MyClass2::getName)
.build();
private final DogTag<MyClass2> dogTag = factory.tag(this);
@Override
public int hashCode() {
return dogTag.hashCode();
}
@Override
public boolean equals(final Object obj) {
return dogTag.equals(obj);
}
}
{code}
(I'm a new contributor, so I'm not sure if this is the best way to suggest a
whole new class. But I'd like to contribute to give people a faster way of
doing Reflection Equals.)
was:
The EqualsBuilder.reflectionEquals() method is very inefficient. It reflects
through all the fields of a class every time it needs to do a comparison. A
faster approach would be to do the reflection once when the class loads, and
re-use it for each instance. This change, however, needs a different API and
couldn't be a drop-in replacement for EqualsBuilder. Instead it would need to
be a new class.
I have written a class that can do this. Performance tests show that it runs
up to 20 times faster, depending on how many fields it needs to compare before
finding a difference.
You can try the class out by going to [https://github.com/SwingGuy1024/DogTags].
The API currently works like this:
{code:java}
public class MyClass {
// fields and methods
private static final DogTag<MyClass> dogTag = DogTag.from(MyClass.class);
@Override
public boolean equals(Object that) {
return dogTag.doEqualsTest(this, that);
}
@Override
public int hashCode() {
return dogTag.doHashCode(this);
}
}{code}
I'm looking into changing the API, so it would work like this:
{code:java}
public class MyClass {
// fields and methods here ...
private final DogTag<MyClass> dogTag = DogTag.from(MyClass.class, this);
@Override
public boolean equals(Object other) {
return dogTag.doEqualsTest(other);
}
@Override
public int hashCode() {
return dogTag.doHashCode();
}
}
{code}
(I'm a new contributor, so I'm not sure if this is the best way to suggest a
whole new class. But I'd like to contribute to give people a faster way of
doing Reflection Equals.)
> Performance of Reflection for equals and hash code can be improved over
> EqualsBuilder
> -------------------------------------------------------------------------------------
>
> Key: LANG-1493
> URL: https://issues.apache.org/jira/browse/LANG-1493
> Project: Commons Lang
> Issue Type: New Feature
> Components: lang.*
> Reporter: Miguel Munoz
> Priority: Major
> Original Estimate: 672h
> Remaining Estimate: 672h
>
> The EqualsBuilder.reflectionEquals() method is very inefficient. It reflects
> through all the fields of a class every time it needs to do a comparison. A
> faster approach would be to do the reflection once when the class loads, and
> re-use it for each instance. This change, however, needs a different API and
> couldn't be a drop-in replacement for EqualsBuilder. Instead it would need to
> be a new class.
> I have written a class that can do this. Performance tests show that it runs
> up to 20 times faster, depending on how many fields it needs to compare
> before finding a difference.
> You can try the class out by going to
> [https://github.com/SwingGuy1024/DogTags].
> The API currently works like this:
>
> {code:java}
> public class MyClass {
> // fields and methods omitted for brevity
>
> // Use reflection to implement equals() and hashCode() based on all non
> transient, non static fields
> private static final DogTag.Factory<MyClass> factory =
> DogTag.create(MyClass.class).build();
> private final DogTag<MyClass> dogTag = factory.tag(this);
>
> @Override
> public boolean equals(Object that) {
> return dogTag.equals(that);
> }
>
> @Override
> public int hashCode() {
> return dogTag.hashCode();
> }
> }{code}
> An alternative way to do this is to specify function pointers
> {code:java}
> public class MyClass2 {
> private String name;
> private int age;
>
> public MyClass2(String name, int age) {
> this.name = name;
> this.age = age;
> }
> public String getName() { return name;}
> public int getAge() { return age;}
>
> private static final DogTag.Factory<MyClass2> factory =
> DogTag.createByLambda(MyClass2.class)
> .addSimple(MyClass2::getAge)
> .addObject(MyClass2::getName)
> .build();
> private final DogTag<MyClass2> dogTag = factory.tag(this);
> @Override
> public int hashCode() {
> return dogTag.hashCode();
> }
> @Override
> public boolean equals(final Object obj) {
> return dogTag.equals(obj);
> }
> }
> {code}
> (I'm a new contributor, so I'm not sure if this is the best way to suggest a
> whole new class. But I'd like to contribute to give people a faster way of
> doing Reflection Equals.)
--
This message was sent by Atlassian Jira
(v8.3.4#803005)