On 11/10/25 19:25, Ernie Rael wrote: > On 25/11/10 9:28 AM, Michael Bien wrote: >> On 11/10/25 17:26, Ernie Rael wrote: >>> On 25/11/08 4:13 PM, Michael Bien wrote: >>>> I ran a little JMH benchmark since this made me curious. >>>> >>>> https://gist.github.com/mbien/8f029092749c590878b9b83b8e79fe53 >>>> >>>> The JVM seems to have some problems to unroll the Objects.hash() method. >>>> Even though It is the least verbose approach, it also makes me less >>>> enthusiastic to switch to it given that >>>> it would be a "generate and forget" situation in both cases where I am not >>>> worried about a few lines more. >>> Should this be filed as a problem with the compiler/hot-spot and/or >>> Objects.hash() method? Do you believe that this performance issue can not >>> be addressed in the JDK? >>> >>> Seems a shame to have multiple ways to do something dependent on how the >>> result is cached, which could change; but it does seems unlikely that if >>> some result is cached, that in the future it will no longer cached. >> not sure I follow. The dev who implements the hash method has control over >> how it is computed and when it is computed. Hash could be as simple as an >> UID and nothing needs to be computed. E.g hash code for Integer 5 is 5 which >> is a pretty good UID for 5. > > IIUC, the discussion is if NB should use Objects.hash() when it generates > code, instead of inlining;
I wouldn't mind to use Objects.hash() as (new) default for NB's code gen and keep the unrolled version as option somewhere in the settings. >> >> also: don't read too much into the small benchmark I quickly wrote out of >> curiosity > > It seemed like the benchmark was/is swaying your thinking. Be nice if it > could be fixed in the JDK. its just a data point for me. The JDK team is working on several jeps which would make inlining calls like this for the JVM easier in future. https://openjdk.org/jeps/500 https://openjdk.org/jeps/526 and of course the whole project valhalla meanwhile: use records where it makes sense -mbien > > -ernie > >> >> best regards, >> >> michael >> >> >> * https://github.com/apache/maven/issues/2481 >> >> >>> I don't suppose there's a marketing coup to be had against Eclipse and >>> Intellij over this issue. >>> >>> IIUC, the hash is used in lookup for many collection types. If the JDK >>> can't fix Objects.hash() performance, I wonder if collection creation >>> could/should have a cache-hash option to force the performance/size >>> tradeoff. >>> >>> -ernie >>> >>> >>>> But when the hash value is cached -> I would probably use the most compact >>>> way to compute it. >>>> >>>> and/or use records of course >>>> >>>> (maven 4 made recently some efforts to cache hash constants since not >>>> re-computing them made a >>>> measurable difference there - esp when the tree involved collections) >>>> >>>> best regards, >>>> michael >>>> >>>> On 11/5/25 23:00, Michael Bien wrote: >>>>> Hi, >>>>> >>>>> The hashCode method generator most likely didn't get updated to use the >>>>> Objects.* utility and does the computation "by hand". >>>>> >>>>> I think this came up on slack before and it would be nice if it could be >>>>> updated to use Objects.hash(...) but nobody got to it so far. >>>>> >>>>> JDK uses a "n = 31*n + obj.hashCode()" loop, NB does the same, just with >>>>> a different prime / start offset and unrolls the loop. >>>>> >>>>> regarding equals: Double.compare() would use Double.doubleToLongBits() >>>>> internally and might be easier to read - something >>>>> NB could change too but its probably not that important. >>>>> >>>>> best regards, >>>>> michael >>>>> >>>>> >>>>> On 11/5/25 22:20, Kenneth Fogel wrote: >>>>>> For a discussion for Java Beans in my writing, I generated the hashCode >>>>>> and equals methods in NetBeans. I then generated the same methods with >>>>>> Eclipse and Intellij. It is the hashCode and equals methods that stood >>>>>> out as Eclipse and Intellij generate the exact same code that is quite >>>>>> different from NetBeans. >>>>>> >>>>>> NetBeans: >>>>>> @Override >>>>>> public int hashCode() { >>>>>> int hash = 3; >>>>>> hash = 97 * hash + Objects.hashCode(this.title); >>>>>> hash = 97 * hash + Objects.hashCode(this.author); >>>>>> hash = 97 * hash + Objects.hashCode(this.publisher); >>>>>> hash = 97 * hash + Objects.hashCode(this.isbn); >>>>>> hash = 97 * hash + this.pages; >>>>>> hash = 97 * hash + this.copiesInStock; >>>>>> hash = 97 * hash + this.copiesSold; >>>>>> hash = 97 * hash + (int) >>>>>> (Double.doubleToLongBits(this.wholesaleCost) ^ >>>>>> (Double.doubleToLongBits(this.wholesaleCost) >>> 32)); >>>>>> hash = 97 * hash + (int) >>>>>> (Double.doubleToLongBits(this.retailPrice) ^ >>>>>> (Double.doubleToLongBits(this.retailPrice) >>> 32)); >>>>>> hash = 97 * hash + (this.suitableForChildren ? 1 : 0); >>>>>> return hash; >>>>>> } >>>>>> >>>>>> Eclipse and IntelliJ: >>>>>> @Override >>>>>> public int hashCode() { >>>>>> return Objects.hash(title, author, publisher, isbn, pages, >>>>>> copiesInStock, copiesSold, wholesaleCost, retailPrice, >>>>>> suitableForChildren); >>>>>> } >>>>>> >>>>>> In NetBeans, why is the initial hash value 3 and then 97 that is always >>>>>> added? Is the fact that 97 + 3 = 100 significant? From the perspective >>>>>> of explaining what this code does, the Eclipse/IntelliJ version is much >>>>>> simpler to describe. >>>>>> >>>>>> Is there a reason for the additional code in the NetBeans version. Is >>>>>> the NetBeans version less prone to false positives, meaning you need to >>>>>> use equals() less often? >>>>>> >>>>>> For the equals() method the difference is also interesting. >>>>>> >>>>>> NetBeans >>>>>> @Override >>>>>> public boolean equals(Object obj) { >>>>>> if (this == obj) { >>>>>> return true; >>>>>> } >>>>>> if (obj == null) { >>>>>> return false; >>>>>> } >>>>>> if (getClass() != obj.getClass()) { >>>>>> return false; >>>>>> } >>>>>> final BookBean other = (BookBean) obj; >>>>>> if (this.pages != other.pages) { >>>>>> return false; >>>>>> } >>>>>> if (this.copiesInStock != other.copiesInStock) { >>>>>> return false; >>>>>> } >>>>>> if (this.copiesSold != other.copiesSold) { >>>>>> return false; >>>>>> } >>>>>> if (Double.doubleToLongBits(this.wholesaleCost) != >>>>>> Double.doubleToLongBits(other.wholesaleCost)) { >>>>>> return false; >>>>>> } >>>>>> if (Double.doubleToLongBits(this.retailPrice) != >>>>>> Double.doubleToLongBits(other.retailPrice)) { >>>>>> return false; >>>>>> } >>>>>> if (this.suitableForChildren != other.suitableForChildren) { >>>>>> return false; >>>>>> } >>>>>> if (!Objects.equals(this.title, other.title)) { >>>>>> return false; >>>>>> } >>>>>> if (!Objects.equals(this.author, other.author)) { >>>>>> return false; >>>>>> } >>>>>> if (!Objects.equals(this.publisher, other.publisher)) { >>>>>> return false; >>>>>> } >>>>>> return Objects.equals(this.isbn, other.isbn); >>>>>> } >>>>>> >>>>>> Eclipse and IntelliJ >>>>>> @Override >>>>>> public boolean equals(Object o) { >>>>>> if (o == null || getClass() != o.getClass()) return false; >>>>>> BookBean bookBean = (BookBean) o; >>>>>> return pages == bookBean.pages && copiesInStock == >>>>>> bookBean.copiesInStock && copiesSold == bookBean.copiesSold && >>>>>> Double.compare(wholesaleCost, bookBean.wholesaleCost) == 0 && >>>>>> Double.compare(retailPrice, bookBean.retailPrice) == 0 && >>>>>> suitableForChildren == bookBean.suitableForChildren && >>>>>> Objects.equals(title, bookBean.title) && Objects.equals(author, >>>>>> bookBean.author) && Objects.equals(publisher, bookBean.publisher) && >>>>>> Objects.equals(isbn, bookBean.isbn); >>>>>> } >>>>>> >>>>>> In this code Eclipse and IntelliJ use Double.compare for comparing >>>>>> fields that are doubles while NetBeans uses Double.doubleToLongBits. >>>>>> >>>>>> Is this even something to worry about? I am not advocating for this code >>>>>> to be the same in all three IDEs. I would like to know if the >>>>>> differences are significant. From what I see and from my limited >>>>>> understanding about how this code performs, I’d guess the >>>>>> IntelliJ/Eclipse code is superior. >>>>>> >>>>>> Ken >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>> --------------------------------------------------------------------- >>>> To unsubscribe, e-mail: [email protected] >>>> For additional commands, e-mail: [email protected] >>>> >>>> For further information about the NetBeans mailing lists, visit: >>>> https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists >>>> >>>> >>>> > --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected] For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists
