Re: RFR: 8280035: Use Class.isInstance instead of Class.isAssignableFrom where applicable [v2]
On Thu, 31 Mar 2022 08:03:23 GMT, Andrey Turbanov wrote: >> Method `Class.isAssignableFrom` is often used in form of: >> >> if (clazz.isAssignableFrom(obj.getClass())) { >> Such condition could be simplified to more shorter and performarnt code >> >> if (clazz.isInstance(obj)) { >> >> Replacement is equivalent if it's known that `obj != null`. >> In JDK codebase there are many such places. >> >> I tried to measure performance via JMH >> >> Class integerClass = Integer.class; >> Class numberClass = Number.class; >> >> Object integerObject = 45666; >> Object doubleObject = 8777d; >> >> @Benchmark >> public boolean integerInteger_isInstance() { >> return integerClass.isInstance(integerObject); >> } >> >> @Benchmark >> public boolean integerInteger_isAssignableFrom() { >> return integerClass.isAssignableFrom(integerObject.getClass()); >> } >> >> @Benchmark >> public boolean integerDouble_isInstance() { >> return integerClass.isInstance(doubleObject); >> } >> >> @Benchmark >> public boolean integerDouble_isAssignableFrom() { >> return integerClass.isAssignableFrom(doubleObject.getClass()); >> } >> >> @Benchmark >> public boolean numberDouble_isInstance() { >> return numberClass.isInstance(doubleObject); >> } >> >> @Benchmark >> public boolean numberDouble_isAssignableFrom() { >> return numberClass.isAssignableFrom(doubleObject.getClass()); >> } >> >> @Benchmark >> public boolean numberInteger_isInstance() { >> return numberClass.isInstance(integerObject); >> } >> >> @Benchmark >> public boolean numberInteger_isAssignableFrom() { >> return numberClass.isAssignableFrom(integerObject.getClass()); >> } >> >> @Benchmark >> public void numberIntegerDouble_isInstance(Blackhole bh) { >> bh.consume(numberClass.isInstance(integerObject)); >> bh.consume(numberClass.isInstance(doubleObject)); >> } >> >> @Benchmark >> public void integerIntegerDouble_isAssignableFrom(Blackhole bh) { >> bh.consume(integerClass.isAssignableFrom(integerObject.getClass())); >> bh.consume(integerClass.isAssignableFrom(doubleObject.getClass())); >> } >> >> `isInstance` is a bit faster than `isAssignableFrom` >> >> Benchmark Mode Cnt Score Error Units >> integerDouble_isAssignableFrom avgt5 1,173 ± 0,026 ns/op >> integerDouble_isInstance avgt5 0,939 ± 0,038 ns/op >> integerIntegerDouble_isAssignableFrom avgt5 2,106 ± 0,068 ns/op >> numberIntegerDouble_isInstance avgt5 1,516 ± 0,046 ns/op >> integerInteger_isAssignableFromavgt5 1,175 ± 0,029 ns/op >> integerInteger_isInstance avgt5 0,886 ± 0,017 ns/op >> numberDouble_isAssignableFrom avgt5 1,172 ± 0,007 ns/op >> numberDouble_isInstanceavgt5 0,891 ± 0,030 ns/op >> numberInteger_isAssignableFrom avgt5 1,169 ± 0,014 ns/op >> numberInteger_isInstance avgt5 0,887 ± 0,016 ns/op > > Andrey Turbanov has updated the pull request incrementally with one > additional commit since the last revision: > > 8280035: Use Class.isInstance instead of Class.isAssignableFrom where > applicable > apply suggestion to avoid second Method.invoke call Thank you for review! - PR: https://git.openjdk.java.net/jdk/pull/7061
Re: RFR: 8280035: Use Class.isInstance instead of Class.isAssignableFrom where applicable [v2]
On Thu, 31 Mar 2022 08:03:23 GMT, Andrey Turbanov wrote: >> Method `Class.isAssignableFrom` is often used in form of: >> >> if (clazz.isAssignableFrom(obj.getClass())) { >> Such condition could be simplified to more shorter and performarnt code >> >> if (clazz.isInstance(obj)) { >> >> Replacement is equivalent if it's known that `obj != null`. >> In JDK codebase there are many such places. >> >> I tried to measure performance via JMH >> >> Class integerClass = Integer.class; >> Class numberClass = Number.class; >> >> Object integerObject = 45666; >> Object doubleObject = 8777d; >> >> @Benchmark >> public boolean integerInteger_isInstance() { >> return integerClass.isInstance(integerObject); >> } >> >> @Benchmark >> public boolean integerInteger_isAssignableFrom() { >> return integerClass.isAssignableFrom(integerObject.getClass()); >> } >> >> @Benchmark >> public boolean integerDouble_isInstance() { >> return integerClass.isInstance(doubleObject); >> } >> >> @Benchmark >> public boolean integerDouble_isAssignableFrom() { >> return integerClass.isAssignableFrom(doubleObject.getClass()); >> } >> >> @Benchmark >> public boolean numberDouble_isInstance() { >> return numberClass.isInstance(doubleObject); >> } >> >> @Benchmark >> public boolean numberDouble_isAssignableFrom() { >> return numberClass.isAssignableFrom(doubleObject.getClass()); >> } >> >> @Benchmark >> public boolean numberInteger_isInstance() { >> return numberClass.isInstance(integerObject); >> } >> >> @Benchmark >> public boolean numberInteger_isAssignableFrom() { >> return numberClass.isAssignableFrom(integerObject.getClass()); >> } >> >> @Benchmark >> public void numberIntegerDouble_isInstance(Blackhole bh) { >> bh.consume(numberClass.isInstance(integerObject)); >> bh.consume(numberClass.isInstance(doubleObject)); >> } >> >> @Benchmark >> public void integerIntegerDouble_isAssignableFrom(Blackhole bh) { >> bh.consume(integerClass.isAssignableFrom(integerObject.getClass())); >> bh.consume(integerClass.isAssignableFrom(doubleObject.getClass())); >> } >> >> `isInstance` is a bit faster than `isAssignableFrom` >> >> Benchmark Mode Cnt Score Error Units >> integerDouble_isAssignableFrom avgt5 1,173 ± 0,026 ns/op >> integerDouble_isInstance avgt5 0,939 ± 0,038 ns/op >> integerIntegerDouble_isAssignableFrom avgt5 2,106 ± 0,068 ns/op >> numberIntegerDouble_isInstance avgt5 1,516 ± 0,046 ns/op >> integerInteger_isAssignableFromavgt5 1,175 ± 0,029 ns/op >> integerInteger_isInstance avgt5 0,886 ± 0,017 ns/op >> numberDouble_isAssignableFrom avgt5 1,172 ± 0,007 ns/op >> numberDouble_isInstanceavgt5 0,891 ± 0,030 ns/op >> numberInteger_isAssignableFrom avgt5 1,169 ± 0,014 ns/op >> numberInteger_isInstance avgt5 0,887 ± 0,016 ns/op > > Andrey Turbanov has updated the pull request incrementally with one > additional commit since the last revision: > > 8280035: Use Class.isInstance instead of Class.isAssignableFrom where > applicable > apply suggestion to avoid second Method.invoke call Marked as reviewed by rriggs (Reviewer). - PR: https://git.openjdk.java.net/jdk/pull/7061
Re: RFR: 8280035: Use Class.isInstance instead of Class.isAssignableFrom where applicable [v2]
On Thu, 31 Mar 2022 08:03:23 GMT, Andrey Turbanov wrote: >> Method `Class.isAssignableFrom` is often used in form of: >> >> if (clazz.isAssignableFrom(obj.getClass())) { >> Such condition could be simplified to more shorter and performarnt code >> >> if (clazz.isInstance(obj)) { >> >> Replacement is equivalent if it's known that `obj != null`. >> In JDK codebase there are many such places. >> >> I tried to measure performance via JMH >> >> Class integerClass = Integer.class; >> Class numberClass = Number.class; >> >> Object integerObject = 45666; >> Object doubleObject = 8777d; >> >> @Benchmark >> public boolean integerInteger_isInstance() { >> return integerClass.isInstance(integerObject); >> } >> >> @Benchmark >> public boolean integerInteger_isAssignableFrom() { >> return integerClass.isAssignableFrom(integerObject.getClass()); >> } >> >> @Benchmark >> public boolean integerDouble_isInstance() { >> return integerClass.isInstance(doubleObject); >> } >> >> @Benchmark >> public boolean integerDouble_isAssignableFrom() { >> return integerClass.isAssignableFrom(doubleObject.getClass()); >> } >> >> @Benchmark >> public boolean numberDouble_isInstance() { >> return numberClass.isInstance(doubleObject); >> } >> >> @Benchmark >> public boolean numberDouble_isAssignableFrom() { >> return numberClass.isAssignableFrom(doubleObject.getClass()); >> } >> >> @Benchmark >> public boolean numberInteger_isInstance() { >> return numberClass.isInstance(integerObject); >> } >> >> @Benchmark >> public boolean numberInteger_isAssignableFrom() { >> return numberClass.isAssignableFrom(integerObject.getClass()); >> } >> >> @Benchmark >> public void numberIntegerDouble_isInstance(Blackhole bh) { >> bh.consume(numberClass.isInstance(integerObject)); >> bh.consume(numberClass.isInstance(doubleObject)); >> } >> >> @Benchmark >> public void integerIntegerDouble_isAssignableFrom(Blackhole bh) { >> bh.consume(integerClass.isAssignableFrom(integerObject.getClass())); >> bh.consume(integerClass.isAssignableFrom(doubleObject.getClass())); >> } >> >> `isInstance` is a bit faster than `isAssignableFrom` >> >> Benchmark Mode Cnt Score Error Units >> integerDouble_isAssignableFrom avgt5 1,173 ± 0,026 ns/op >> integerDouble_isInstance avgt5 0,939 ± 0,038 ns/op >> integerIntegerDouble_isAssignableFrom avgt5 2,106 ± 0,068 ns/op >> numberIntegerDouble_isInstance avgt5 1,516 ± 0,046 ns/op >> integerInteger_isAssignableFromavgt5 1,175 ± 0,029 ns/op >> integerInteger_isInstance avgt5 0,886 ± 0,017 ns/op >> numberDouble_isAssignableFrom avgt5 1,172 ± 0,007 ns/op >> numberDouble_isInstanceavgt5 0,891 ± 0,030 ns/op >> numberInteger_isAssignableFrom avgt5 1,169 ± 0,014 ns/op >> numberInteger_isInstance avgt5 0,887 ± 0,016 ns/op > > Andrey Turbanov has updated the pull request incrementally with one > additional commit since the last revision: > > 8280035: Use Class.isInstance instead of Class.isAssignableFrom where > applicable > apply suggestion to avoid second Method.invoke call Any more reviewers, please?) - PR: https://git.openjdk.java.net/jdk/pull/7061
Re: RFR: 8280035: Use Class.isInstance instead of Class.isAssignableFrom where applicable [v2]
On Tue, 10 May 2022 11:31:16 GMT, Andrey Turbanov wrote: >> src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java line >> 230: >> >>> 228: List l = new ArrayList<>(); >>> 229: for (Class c : categoryMap.keySet()) { >>> 230: if (c.isInstance(provider)) { >> >> Can this be reached if `provider` is null? If yes there could be a change of >> behaviour as the previous code would have thrown NPE. > > No. This method is called from 3 places, and there 3 null checks before the > method call. Thanks for double checking! LGTM then. - PR: https://git.openjdk.java.net/jdk/pull/7061
Re: RFR: 8280035: Use Class.isInstance instead of Class.isAssignableFrom where applicable [v2]
On Tue, 10 May 2022 11:10:50 GMT, Daniel Fuchs wrote: >> Andrey Turbanov has updated the pull request incrementally with one >> additional commit since the last revision: >> >> 8280035: Use Class.isInstance instead of Class.isAssignableFrom where >> applicable >> apply suggestion to avoid second Method.invoke call > > src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java line > 230: > >> 228: List l = new ArrayList<>(); >> 229: for (Class c : categoryMap.keySet()) { >> 230: if (c.isInstance(provider)) { > > Can this be reached if `provider` is null? If yes there could be a change of > behaviour as the previous code would have thrown NPE. No. This method is called from 3 places, and there 3 null checks before the method call. - PR: https://git.openjdk.java.net/jdk/pull/7061
Re: RFR: 8280035: Use Class.isInstance instead of Class.isAssignableFrom where applicable [v2]
On Thu, 31 Mar 2022 08:03:23 GMT, Andrey Turbanov wrote: >> Method `Class.isAssignableFrom` is often used in form of: >> >> if (clazz.isAssignableFrom(obj.getClass())) { >> Such condition could be simplified to more shorter and performarnt code >> >> if (clazz.isInstance(obj)) { >> >> Replacement is equivalent if it's known that `obj != null`. >> In JDK codebase there are many such places. >> >> I tried to measure performance via JMH >> >> Class integerClass = Integer.class; >> Class numberClass = Number.class; >> >> Object integerObject = 45666; >> Object doubleObject = 8777d; >> >> @Benchmark >> public boolean integerInteger_isInstance() { >> return integerClass.isInstance(integerObject); >> } >> >> @Benchmark >> public boolean integerInteger_isAssignableFrom() { >> return integerClass.isAssignableFrom(integerObject.getClass()); >> } >> >> @Benchmark >> public boolean integerDouble_isInstance() { >> return integerClass.isInstance(doubleObject); >> } >> >> @Benchmark >> public boolean integerDouble_isAssignableFrom() { >> return integerClass.isAssignableFrom(doubleObject.getClass()); >> } >> >> @Benchmark >> public boolean numberDouble_isInstance() { >> return numberClass.isInstance(doubleObject); >> } >> >> @Benchmark >> public boolean numberDouble_isAssignableFrom() { >> return numberClass.isAssignableFrom(doubleObject.getClass()); >> } >> >> @Benchmark >> public boolean numberInteger_isInstance() { >> return numberClass.isInstance(integerObject); >> } >> >> @Benchmark >> public boolean numberInteger_isAssignableFrom() { >> return numberClass.isAssignableFrom(integerObject.getClass()); >> } >> >> @Benchmark >> public void numberIntegerDouble_isInstance(Blackhole bh) { >> bh.consume(numberClass.isInstance(integerObject)); >> bh.consume(numberClass.isInstance(doubleObject)); >> } >> >> @Benchmark >> public void integerIntegerDouble_isAssignableFrom(Blackhole bh) { >> bh.consume(integerClass.isAssignableFrom(integerObject.getClass())); >> bh.consume(integerClass.isAssignableFrom(doubleObject.getClass())); >> } >> >> `isInstance` is a bit faster than `isAssignableFrom` >> >> Benchmark Mode Cnt Score Error Units >> integerDouble_isAssignableFrom avgt5 1,173 ± 0,026 ns/op >> integerDouble_isInstance avgt5 0,939 ± 0,038 ns/op >> integerIntegerDouble_isAssignableFrom avgt5 2,106 ± 0,068 ns/op >> numberIntegerDouble_isInstance avgt5 1,516 ± 0,046 ns/op >> integerInteger_isAssignableFromavgt5 1,175 ± 0,029 ns/op >> integerInteger_isInstance avgt5 0,886 ± 0,017 ns/op >> numberDouble_isAssignableFrom avgt5 1,172 ± 0,007 ns/op >> numberDouble_isInstanceavgt5 0,891 ± 0,030 ns/op >> numberInteger_isAssignableFrom avgt5 1,169 ± 0,014 ns/op >> numberInteger_isInstance avgt5 0,887 ± 0,016 ns/op > > Andrey Turbanov has updated the pull request incrementally with one > additional commit since the last revision: > > 8280035: Use Class.isInstance instead of Class.isAssignableFrom where > applicable > apply suggestion to avoid second Method.invoke call src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java line 230: > 228: List l = new ArrayList<>(); > 229: for (Class c : categoryMap.keySet()) { > 230: if (c.isInstance(provider)) { Can this be reached if `provider` is null? If yes there could be a change of behaviour as the previous code would have thrown NPE. - PR: https://git.openjdk.java.net/jdk/pull/7061
Re: RFR: 8280035: Use Class.isInstance instead of Class.isAssignableFrom where applicable [v2]
On Thu, 31 Mar 2022 08:03:23 GMT, Andrey Turbanov wrote: >> Method `Class.isAssignableFrom` is often used in form of: >> >> if (clazz.isAssignableFrom(obj.getClass())) { >> Such condition could be simplified to more shorter and performarnt code >> >> if (clazz.isInstance(obj)) { >> >> Replacement is equivalent if it's known that `obj != null`. >> In JDK codebase there are many such places. >> >> I tried to measure performance via JMH >> >> Class integerClass = Integer.class; >> Class numberClass = Number.class; >> >> Object integerObject = 45666; >> Object doubleObject = 8777d; >> >> @Benchmark >> public boolean integerInteger_isInstance() { >> return integerClass.isInstance(integerObject); >> } >> >> @Benchmark >> public boolean integerInteger_isAssignableFrom() { >> return integerClass.isAssignableFrom(integerObject.getClass()); >> } >> >> @Benchmark >> public boolean integerDouble_isInstance() { >> return integerClass.isInstance(doubleObject); >> } >> >> @Benchmark >> public boolean integerDouble_isAssignableFrom() { >> return integerClass.isAssignableFrom(doubleObject.getClass()); >> } >> >> @Benchmark >> public boolean numberDouble_isInstance() { >> return numberClass.isInstance(doubleObject); >> } >> >> @Benchmark >> public boolean numberDouble_isAssignableFrom() { >> return numberClass.isAssignableFrom(doubleObject.getClass()); >> } >> >> @Benchmark >> public boolean numberInteger_isInstance() { >> return numberClass.isInstance(integerObject); >> } >> >> @Benchmark >> public boolean numberInteger_isAssignableFrom() { >> return numberClass.isAssignableFrom(integerObject.getClass()); >> } >> >> @Benchmark >> public void numberIntegerDouble_isInstance(Blackhole bh) { >> bh.consume(numberClass.isInstance(integerObject)); >> bh.consume(numberClass.isInstance(doubleObject)); >> } >> >> @Benchmark >> public void integerIntegerDouble_isAssignableFrom(Blackhole bh) { >> bh.consume(integerClass.isAssignableFrom(integerObject.getClass())); >> bh.consume(integerClass.isAssignableFrom(doubleObject.getClass())); >> } >> >> `isInstance` is a bit faster than `isAssignableFrom` >> >> Benchmark Mode Cnt Score Error Units >> integerDouble_isAssignableFrom avgt5 1,173 ± 0,026 ns/op >> integerDouble_isInstance avgt5 0,939 ± 0,038 ns/op >> integerIntegerDouble_isAssignableFrom avgt5 2,106 ± 0,068 ns/op >> numberIntegerDouble_isInstance avgt5 1,516 ± 0,046 ns/op >> integerInteger_isAssignableFromavgt5 1,175 ± 0,029 ns/op >> integerInteger_isInstance avgt5 0,886 ± 0,017 ns/op >> numberDouble_isAssignableFrom avgt5 1,172 ± 0,007 ns/op >> numberDouble_isInstanceavgt5 0,891 ± 0,030 ns/op >> numberInteger_isAssignableFrom avgt5 1,169 ± 0,014 ns/op >> numberInteger_isInstance avgt5 0,887 ± 0,016 ns/op > > Andrey Turbanov has updated the pull request incrementally with one > additional commit since the last revision: > > 8280035: Use Class.isInstance instead of Class.isAssignableFrom where > applicable > apply suggestion to avoid second Method.invoke call Marked as reviewed by prr (Reviewer). - PR: https://git.openjdk.java.net/jdk/pull/7061