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

Cache types in ConstructorMapper #2650

Closed
wants to merge 3 commits into from

Conversation

elonazoulay
Copy link
Contributor

Cache types to avoid expensive calculations in ConstructorInstanceFactory.
Following up on suggestions from #2648.

The constructor lookup should be quick: hashCode is class name and equals compares parameters using object equality.

@elonazoulay elonazoulay marked this pull request as draft February 22, 2024 16:07
@@ -75,6 +75,9 @@ public final class ConstructorMapper<T> implements RowMapper<T> {
+ "that your result set has the columns expected, annotate the "
+ "parameter names explicitly with @ColumnName, or annotate nullable parameters as @Nullable";


static final Map<Constructor, Type[]> CONSTRUCTOR_CACHE = new ConcurrentHashMap<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be simpler to have that in the factory and make it private?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try that out, thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated. Originally I was going to use a guava cache but I see that guava is only imported in test scope. lmk if you think it's a good idea to add a size limit, cache stats, ability to clear cache, disable cache (maybe for benchmarking), etc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not depend on Guava from Jdbi core, since it is a huge dep to push onto our users. Additionally, there are numerous known cache bugs that seemingly will never get fixed. The Guava CacheBuilder javadocs tell you to use Caffeine instead to avoid such bugs.

I think for a simple use case like this, a synchronized weak hash map is good enough. A map that caches JVM entities like constructors and classes will not grow without bound, so there is no need to size it.

@hgschmie
Copy link
Contributor

Looks good. Lmk when you move it from draft to ready.

@elonazoulay elonazoulay marked this pull request as ready for review February 23, 2024 07:40
@elonazoulay
Copy link
Contributor Author

Updated, lmk if it's good to go whenever you have a chance, thanks!

Copy link
Member

@stevenschlansker stevenschlansker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One note about inadvertent retention of classes. Otherwise LGTM

@@ -27,19 +29,18 @@
import static java.util.Objects.requireNonNull;

class ConstructorInstanceFactory<T> extends InstanceFactory<T> {
private final Constructor<T> constructor;
private static final Map<Constructor, Type[]> CONSTRUCTOR_CACHE = new ConcurrentHashMap<>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will prevent the JVM from unloading any class that the ConstructorMapper ever considers, since it keeps a static strong reference to the Constructor.

Would the change work just as well with a synchronizedMap(new WeakHashMap<>()) or something like that? Then, the JVM would be able to unload classes since we do not strongly retain their Constructors.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good, will try all of these ideas out and update, thanks!

@stevenschlansker
Copy link
Member

stevenschlansker commented Feb 24, 2024

This is a broader change than the scope that you're trying to accomplish here, but I think the performance would be even better if we construct and cache a MethodHandle that invokes the constructor or factory method.

@stevenschlansker
Copy link
Member

One last thought: it would be nice if we could see the improvement in a benchmark in benchmarks/. I think the improvement is clear enough from reading that this is not strictly required, but I think it's a good habit for us to get into to prove the benefit of such changes through repeatable benchmarks.

@elonazoulay
Copy link
Contributor Author

Updated, will run the benchmarks on the commit before the record constructor workaround, before the this commit and then after this commit and post the results to the pr. Thanks for all the ideas!

@elonazoulay
Copy link
Contributor Author

Just working through the ci failures, will update.

@elonazoulay
Copy link
Contributor Author

elonazoulay commented Mar 1, 2024

Update: added a commit to cache the types and method handle in the instance factory.
Also found that the constructor benchmark was invoking a different benchmark, first commit. Should that be a separate small pr?

I'm running the benchmarks.jar locally, taking a few hours but I will post the results when it's done:)


class ConstructorInstanceFactory<T> extends InstanceFactory<T> {
private final Constructor<T> constructor;
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lmk if this shouldn't be cached.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if you want the weak hashmap added back vs caching in the constructor instance factory (saved the previous version, so I can quickly update).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I think there is a bit of a misunderstanding here. I didn't mean to cache the lookup factory instance itself, but the constructorHandle instance itself.

Something like SynchronizedMap<WeakHashMap<ConstructorHandleAndTypes, MethodHandle>>> (referring to the key type from the other PR)

Sorry I wasn't clear, and sorry for taking so long to respond! Been a busy couple weeks at work.


class ConstructorInstanceFactory<T> extends InstanceFactory<T> {
private final Constructor<T> constructor;
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if you want the weak hashmap added back vs caching in the constructor instance factory (saved the previous version, so I can quickly update).

@@ -207,14 +207,14 @@ private Optional<RowMapper<T>> createSpecializedRowMapper(StatementContext ctx,
List<String> unmatchedColumns) {
final int count = factory.getParameterCount();
final Parameter[] parameters = factory.getParameters();
final Type[] types = factory.getTypes();
final List<Type> types = factory.getTypes();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to convert to list due to error about exposing an array. Thinking to change the api to store the array internally and change the signature to getType(index), wdyt?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds ok

@@ -44,10 +46,10 @@ Parameter[] getParameters() {
return executable.getParameters();
}

Type[] getTypes() {
List<Type> getTypes() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here - should it be Type getType(int index)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK by me

Copy link

sonarcloud bot commented Mar 2, 2024

Quality Gate Passed Quality Gate passed

Issues
3 New issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
0.0% Duplication on New Code

See analysis details on SonarCloud

@elonazoulay
Copy link
Contributor Author

elonazoulay commented Mar 3, 2024

Here are the benchmarks:

Benchmark with the code in this pr:

# Run complete. Total time: 06:05:25
Benchmark                                                              Mode  Cnt       Score      Error   Units
BeanBindingBenchmark.batchJdbc                                        thrpt   20       7.111 ±    0.059   ops/s
BeanBindingBenchmark.batchJdbiBean                                    thrpt   20       6.709 ±    0.082   ops/s
BeanBindingBenchmark.batchJdbiMap                                     thrpt   20       5.218 ±    0.175   ops/s
BeanBindingBenchmark.batchJdbiNamed                                   thrpt   20       5.427 ±    0.160   ops/s
BeanBindingBenchmark.batchJdbiPositional                              thrpt   20       4.993 ±    0.057   ops/s
BeanBindingBenchmark.oneJdbc                                          thrpt   20      20.670 ±    0.268   ops/s
BeanBindingBenchmark.oneJdbi                                          thrpt   20      10.243 ±    0.180   ops/s
QualifiersBenchmark.eq0To0                                            thrpt   20      13.877 ±    0.942  ops/us
QualifiersBenchmark.eq1To1                                            thrpt   20      11.909 ±    0.849  ops/us
QualifiersBenchmark.eq2To2                                            thrpt   20       9.382 ±    0.565  ops/us
QualifiersBenchmark.eq3To3                                            thrpt   20       5.645 ±    0.156  ops/us
QualifiersBenchmark.eq4To4                                            thrpt   20       2.845 ±    0.106  ops/us
QualifiersBenchmark.mapQualifiedBean                                  thrpt   20       0.079 ±    0.001  ops/us
QualifiersBenchmark.mapUnqualifiedBean                                thrpt   20       0.079 ±    0.001  ops/us
QualifiersBenchmark.neq1To0                                           thrpt   20      13.196 ±    1.113  ops/us
QualifiersBenchmark.neq1To1                                           thrpt   20      10.560 ±    1.215  ops/us
QualifiersBenchmark.neq2To2                                           thrpt   20       9.995 ±    1.002  ops/us
QualifiersBenchmark.neq3To3                                           thrpt   20       7.693 ±    1.142  ops/us
QualifiersBenchmark.neq4To4                                           thrpt   20       4.058 ±    0.735  ops/us
QualifiersBenchmark.qualifiedType0                                    thrpt   20      29.724 ±    0.196  ops/us
QualifiersBenchmark.qualifiedType1                                    thrpt   20      29.700 ±    0.123  ops/us
QualifiersBenchmark.qualifiedType2                                    thrpt   20      29.737 ±    0.040  ops/us
QualifiersBenchmark.qualifiedType3                                    thrpt   20      29.560 ±    0.306  ops/us
QualifiersBenchmark.qualifiedType4                                    thrpt   20      29.628 ±    0.179  ops/us
sqlobject.H2SqlObjectV3Benchmark.attach                               thrpt   40      46.903 ±    0.236  ops/ms
sqlobject.H2SqlObjectV3Benchmark.fluentInsertGeneratedKeyBindBean     thrpt   40     128.309 ±    1.116  ops/ms
sqlobject.H2SqlObjectV3Benchmark.fluentInsertGeneratedKeyValues       thrpt   40     140.087 ±    0.577  ops/ms
sqlobject.H2SqlObjectV3Benchmark.fluentSelectOne                      thrpt   40     172.081 ±    0.337  ops/ms
sqlobject.H2SqlObjectV3Benchmark.sqlobjectInsertGeneratedKeyBindBean  thrpt   40     127.652 ±    0.507  ops/ms
sqlobject.H2SqlObjectV3Benchmark.sqlobjectInsertGeneratedKeyValues    thrpt   40     129.491 ±    1.264  ops/ms
sqlobject.H2SqlObjectV3Benchmark.sqlobjectInsertRowCountBindBean      thrpt   40     141.870 ±    1.145  ops/ms
sqlobject.H2SqlObjectV3Benchmark.sqlobjectInsertRowCountValues        thrpt   40     146.427 ±    0.599  ops/ms
sqlobject.H2SqlObjectV3Benchmark.sqlobjectSelectOne                   thrpt   40     151.959 ±    1.535  ops/ms
sqlobject.PGSqlObjectV3Benchmark.attach                               thrpt   40      38.193 ±    0.195  ops/ms
sqlobject.PGSqlObjectV3Benchmark.fluentInsertGeneratedKeyBindBean     thrpt   40      12.775 ±    0.133  ops/ms
sqlobject.PGSqlObjectV3Benchmark.fluentInsertGeneratedKeyValues       thrpt   40      12.724 ±    0.235  ops/ms
sqlobject.PGSqlObjectV3Benchmark.fluentSelectOne                      thrpt   40      19.649 ±    0.227  ops/ms
sqlobject.PGSqlObjectV3Benchmark.sqlobjectInsertGeneratedKeyBindBean  thrpt   40      12.785 ±    0.324  ops/ms
sqlobject.PGSqlObjectV3Benchmark.sqlobjectInsertGeneratedKeyValues    thrpt   40      12.879 ±    0.244  ops/ms
sqlobject.PGSqlObjectV3Benchmark.sqlobjectInsertRowCountBindBean      thrpt   40      15.132 ±    0.283  ops/ms
sqlobject.PGSqlObjectV3Benchmark.sqlobjectInsertRowCountValues        thrpt   40      15.145 ±    0.432  ops/ms
sqlobject.PGSqlObjectV3Benchmark.sqlobjectSelectOne                   thrpt   40      18.895 ±    0.254  ops/ms
sqlobject.SqlObjectOperationBenchmark.classRegistered                 thrpt   40       3.446 ±    0.026  ops/ms
sqlobject.SqlObjectOperationBenchmark.jdbiRegistered                  thrpt   40       3.572 ±    0.022  ops/ms
sqlobject.SqlObjectOperationBenchmark.methodRegistered                thrpt   40       3.475 ±    0.023  ops/ms
CaseInsensitiveStringEqualsBenchmark.collatorEqualsCopy                avgt    5      19.548 ±    0.153   ns/op
CaseInsensitiveStringEqualsBenchmark.collatorEqualsOther               avgt    5     456.382 ±   31.551   ns/op
CaseInsensitiveStringEqualsBenchmark.collatorEqualsRandomCase          avgt    5    3229.864 ±   22.291   ns/op
CaseInsensitiveStringEqualsBenchmark.equalsIgnoreCaseCopy              avgt    5      10.959 ±    0.159   ns/op
CaseInsensitiveStringEqualsBenchmark.equalsIgnoreCaseOther             avgt    5       5.506 ±    0.133   ns/op
CaseInsensitiveStringEqualsBenchmark.equalsIgnoreCaseRandomCase        avgt    5      14.551 ±    0.132   ns/op
CaseInsensitiveStringEqualsBenchmark.stringEquals                      avgt    5       3.754 ±    0.036   ns/op
CaseInsensitiveStringEqualsBenchmark.stringNotEquals                   avgt    5       3.035 ±    0.073   ns/op
CaseInsensitiveStringEqualsBenchmark.toLowerCaseEqualsCopy             avgt    5      39.229 ±    0.104   ns/op
CaseInsensitiveStringEqualsBenchmark.toLowerCaseEqualsOther            avgt    5      32.375 ±    0.185   ns/op
CaseInsensitiveStringEqualsBenchmark.toLowerCaseEqualsRandomCase       avgt    5      41.720 ±    0.087   ns/op
ConstructorBenchmark.constructorMhInvoke                               avgt   20       7.037 ±    0.009   ns/op
ConstructorBenchmark.constructorMhInvokeArgs                           avgt   20     119.362 ±    1.702   ns/op
ConstructorBenchmark.constructorMhInvokeExact                          avgt   20       2.731 ±    0.010   ns/op
ConstructorBenchmark.constructorMhInvokeExactAsType                    avgt   20       2.736 ±    0.006   ns/op
ConstructorBenchmark.constructorNonfinalMhInvokeExact                  avgt   20       7.274 ±    0.024   ns/op
ConstructorBenchmark.jcuCheckedCreate                                  avgt   20    1199.505 ±   43.661   ns/op
ConstructorBenchmark.jcuFindInstantiate                                avgt   20      21.109 ±    0.065   ns/op
EnumMapperBenchmark.mapByExactName                                     avgt    5  264623.009 ± 2022.845   ns/op
EnumMapperBenchmark.mapByOrdinal                                       avgt    5  225109.150 ± 2120.965   ns/op
EnumMapperBenchmark.mapByRandomCaseName                                avgt    5  283579.587 ± 2092.028   ns/op

Benchmark for the weak hashmap version of this pr:

# Run complete. Total time: 06:05:27
Benchmark                                                              Mode  Cnt       Score      Error   Units
BeanBindingBenchmark.batchJdbc                                        thrpt   20       7.148 ±    0.073   ops/s
BeanBindingBenchmark.batchJdbiBean                                    thrpt   20       6.726 ±    0.109   ops/s
BeanBindingBenchmark.batchJdbiMap                                     thrpt   20       5.319 ±    0.061   ops/s
BeanBindingBenchmark.batchJdbiNamed                                   thrpt   20       5.197 ±    0.117   ops/s
BeanBindingBenchmark.batchJdbiPositional                              thrpt   20       4.996 ±    0.056   ops/s
BeanBindingBenchmark.oneJdbc                                          thrpt   20      20.750 ±    0.295   ops/s
BeanBindingBenchmark.oneJdbi                                          thrpt   20      10.359 ±    0.117   ops/s
QualifiersBenchmark.eq0To0                                            thrpt   20      12.563 ±    1.002  ops/us
QualifiersBenchmark.eq1To1                                            thrpt   20      11.341 ±    0.786  ops/us
QualifiersBenchmark.eq2To2                                            thrpt   20      10.160 ±    0.572  ops/us
QualifiersBenchmark.eq3To3                                            thrpt   20       5.715 ±    0.158  ops/us
QualifiersBenchmark.eq4To4                                            thrpt   20       2.942 ±    0.176  ops/us
QualifiersBenchmark.mapQualifiedBean                                  thrpt   20       0.078 ±    0.001  ops/us
QualifiersBenchmark.mapUnqualifiedBean                                thrpt   20       0.079 ±    0.001  ops/us
QualifiersBenchmark.neq1To0                                           thrpt   20      14.417 ±    0.047  ops/us
QualifiersBenchmark.neq1To1                                           thrpt   20       9.973 ±    0.066  ops/us
QualifiersBenchmark.neq2To2                                           thrpt   20       9.574 ±    1.145  ops/us
QualifiersBenchmark.neq3To3                                           thrpt   20       8.543 ±    0.731  ops/us
QualifiersBenchmark.neq4To4                                           thrpt   20       3.619 ±    0.625  ops/us
QualifiersBenchmark.qualifiedType0                                    thrpt   20      29.733 ±    0.058  ops/us
QualifiersBenchmark.qualifiedType1                                    thrpt   20      29.752 ±    0.040  ops/us
QualifiersBenchmark.qualifiedType2                                    thrpt   20      29.768 ±    0.033  ops/us
QualifiersBenchmark.qualifiedType3                                    thrpt   20      29.729 ±    0.046  ops/us
QualifiersBenchmark.qualifiedType4                                    thrpt   20      29.730 ±    0.050  ops/us
sqlobject.H2SqlObjectV3Benchmark.attach                               thrpt   40      47.138 ±    0.033  ops/ms
sqlobject.H2SqlObjectV3Benchmark.fluentInsertGeneratedKeyBindBean     thrpt   40     128.458 ±    0.826  ops/ms
sqlobject.H2SqlObjectV3Benchmark.fluentInsertGeneratedKeyValues       thrpt   40     139.702 ±    0.393  ops/ms
sqlobject.H2SqlObjectV3Benchmark.fluentSelectOne                      thrpt   40     172.776 ±    0.638  ops/ms
sqlobject.H2SqlObjectV3Benchmark.sqlobjectInsertGeneratedKeyBindBean  thrpt   40     126.185 ±    0.873  ops/ms
sqlobject.H2SqlObjectV3Benchmark.sqlobjectInsertGeneratedKeyValues    thrpt   40     128.793 ±    1.106  ops/ms
sqlobject.H2SqlObjectV3Benchmark.sqlobjectInsertRowCountBindBean      thrpt   40     142.768 ±    0.851  ops/ms
sqlobject.H2SqlObjectV3Benchmark.sqlobjectInsertRowCountValues        thrpt   40     145.498 ±    1.890  ops/ms
sqlobject.H2SqlObjectV3Benchmark.sqlobjectSelectOne                   thrpt   40     149.694 ±    1.044  ops/ms
sqlobject.PGSqlObjectV3Benchmark.attach                               thrpt   40      38.282 ±    0.193  ops/ms
sqlobject.PGSqlObjectV3Benchmark.fluentInsertGeneratedKeyBindBean     thrpt   40      12.741 ±    0.311  ops/ms
sqlobject.PGSqlObjectV3Benchmark.fluentInsertGeneratedKeyValues       thrpt   40      13.114 ±    0.252  ops/ms
sqlobject.PGSqlObjectV3Benchmark.fluentSelectOne                      thrpt   40      19.229 ±    0.333  ops/ms
sqlobject.PGSqlObjectV3Benchmark.sqlobjectInsertGeneratedKeyBindBean  thrpt   40      12.810 ±    0.235  ops/ms
sqlobject.PGSqlObjectV3Benchmark.sqlobjectInsertGeneratedKeyValues    thrpt   40      12.664 ±    0.157  ops/ms
sqlobject.PGSqlObjectV3Benchmark.sqlobjectInsertRowCountBindBean      thrpt   40      14.555 ±    0.473  ops/ms
sqlobject.PGSqlObjectV3Benchmark.sqlobjectInsertRowCountValues        thrpt   40      14.677 ±    0.407  ops/ms
sqlobject.PGSqlObjectV3Benchmark.sqlobjectSelectOne                   thrpt   40      18.681 ±    0.219  ops/ms
sqlobject.SqlObjectOperationBenchmark.classRegistered                 thrpt   40       3.459 ±    0.023  ops/ms
sqlobject.SqlObjectOperationBenchmark.jdbiRegistered                  thrpt   40       3.579 ±    0.026  ops/ms
sqlobject.SqlObjectOperationBenchmark.methodRegistered                thrpt   40       3.461 ±    0.024  ops/ms
CaseInsensitiveStringEqualsBenchmark.collatorEqualsCopy                avgt    5      19.627 ±    0.343   ns/op
CaseInsensitiveStringEqualsBenchmark.collatorEqualsOther               avgt    5     458.300 ±   29.416   ns/op
CaseInsensitiveStringEqualsBenchmark.collatorEqualsRandomCase          avgt    5    3201.441 ±   29.365   ns/op
CaseInsensitiveStringEqualsBenchmark.equalsIgnoreCaseCopy              avgt    5      10.964 ±    0.052   ns/op
CaseInsensitiveStringEqualsBenchmark.equalsIgnoreCaseOther             avgt    5       5.495 ±    0.177   ns/op
CaseInsensitiveStringEqualsBenchmark.equalsIgnoreCaseRandomCase        avgt    5      16.808 ±   12.281   ns/op
CaseInsensitiveStringEqualsBenchmark.stringEquals                      avgt    5       3.756 ±    0.021   ns/op
CaseInsensitiveStringEqualsBenchmark.stringNotEquals                   avgt    5       3.034 ±    0.050   ns/op
CaseInsensitiveStringEqualsBenchmark.toLowerCaseEqualsCopy             avgt    5      40.137 ±    0.067   ns/op
CaseInsensitiveStringEqualsBenchmark.toLowerCaseEqualsOther            avgt    5      24.571 ±    0.078   ns/op
CaseInsensitiveStringEqualsBenchmark.toLowerCaseEqualsRandomCase       avgt    5      36.714 ±    0.137   ns/op
ConstructorBenchmark.constructorMhInvoke                               avgt   20       7.164 ±    0.159   ns/op
ConstructorBenchmark.constructorMhInvokeArgs                           avgt   20     119.366 ±    1.628   ns/op
ConstructorBenchmark.constructorMhInvokeExact                          avgt   20       2.743 ±    0.016   ns/op
ConstructorBenchmark.constructorMhInvokeExactAsType                    avgt   20       2.740 ±    0.006   ns/op
ConstructorBenchmark.constructorNonfinalMhInvokeExact                  avgt   20       7.287 ±    0.043   ns/op
ConstructorBenchmark.jcuCheckedCreate                                  avgt   20    1141.730 ±    5.817   ns/op
ConstructorBenchmark.jcuFindInstantiate                                avgt   20      21.124 ±    0.068   ns/op
EnumMapperBenchmark.mapByExactName                                     avgt    5  266533.012 ±  692.077   ns/op
EnumMapperBenchmark.mapByOrdinal                                       avgt    5  224933.755 ± 2743.701   ns/op
EnumMapperBenchmark.mapByRandomCaseName                                avgt    5  284308.595 ± 1817.295   ns/op

Benchmark before the record constructor pr:

# Run complete. Total time: 06:05:26
Benchmark                                                              Mode  Cnt       Score      Error   Units
BeanBindingBenchmark.batchJdbc                                        thrpt   20       7.115 ±    0.093   ops/s
BeanBindingBenchmark.batchJdbiBean                                    thrpt   20       6.752 ±    0.110   ops/s
BeanBindingBenchmark.batchJdbiMap                                     thrpt   20       5.105 ±    0.062   ops/s
BeanBindingBenchmark.batchJdbiNamed                                   thrpt   20       5.322 ±    0.129   ops/s
BeanBindingBenchmark.batchJdbiPositional                              thrpt   20       4.956 ±    0.040   ops/s
BeanBindingBenchmark.oneJdbc                                          thrpt   20      20.865 ±    0.241   ops/s
BeanBindingBenchmark.oneJdbi                                          thrpt   20      10.244 ±    0.065   ops/s
QualifiersBenchmark.eq0To0                                            thrpt   20      13.850 ±    1.071  ops/us
QualifiersBenchmark.eq1To1                                            thrpt   20      12.857 ±    0.072  ops/us
QualifiersBenchmark.eq2To2                                            thrpt   20       9.787 ±    0.706  ops/us
QualifiersBenchmark.eq3To3                                            thrpt   20       5.553 ±    0.173  ops/us
QualifiersBenchmark.eq4To4                                            thrpt   20       2.728 ±    0.201  ops/us
QualifiersBenchmark.mapQualifiedBean                                  thrpt   20       0.078 ±    0.001  ops/us
QualifiersBenchmark.mapUnqualifiedBean                                thrpt   20       0.078 ±    0.001  ops/us
QualifiersBenchmark.neq1To0                                           thrpt   20      13.143 ±    1.159  ops/us
QualifiersBenchmark.neq1To1                                           thrpt   20       9.991 ±    0.023  ops/us
QualifiersBenchmark.neq2To2                                           thrpt   20       9.816 ±    0.146  ops/us
QualifiersBenchmark.neq3To3                                           thrpt   20       7.941 ±    1.334  ops/us
QualifiersBenchmark.neq4To4                                           thrpt   20       3.931 ±    0.690  ops/us
QualifiersBenchmark.qualifiedType0                                    thrpt   20      27.341 ±    3.671  ops/us
QualifiersBenchmark.qualifiedType1                                    thrpt   20      29.658 ±    0.235  ops/us
QualifiersBenchmark.qualifiedType2                                    thrpt   20      29.772 ±    0.203  ops/us
QualifiersBenchmark.qualifiedType3                                    thrpt   20      29.748 ±    0.039  ops/us
QualifiersBenchmark.qualifiedType4                                    thrpt   20      29.680 ±    0.085  ops/us
sqlobject.H2SqlObjectV3Benchmark.attach                               thrpt   40      46.982 ±    0.158  ops/ms
sqlobject.H2SqlObjectV3Benchmark.fluentInsertGeneratedKeyBindBean     thrpt   40     128.415 ±    1.119  ops/ms
sqlobject.H2SqlObjectV3Benchmark.fluentInsertGeneratedKeyValues       thrpt   40     140.853 ±    0.581  ops/ms
sqlobject.H2SqlObjectV3Benchmark.fluentSelectOne                      thrpt   40     171.517 ±    1.176  ops/ms
sqlobject.H2SqlObjectV3Benchmark.sqlobjectInsertGeneratedKeyBindBean  thrpt   40     127.278 ±    0.513  ops/ms
sqlobject.H2SqlObjectV3Benchmark.sqlobjectInsertGeneratedKeyValues    thrpt   40     128.034 ±    0.719  ops/ms
sqlobject.H2SqlObjectV3Benchmark.sqlobjectInsertRowCountBindBean      thrpt   40     142.122 ±    1.059  ops/ms
sqlobject.H2SqlObjectV3Benchmark.sqlobjectInsertRowCountValues        thrpt   40     146.135 ±    1.120  ops/ms
sqlobject.H2SqlObjectV3Benchmark.sqlobjectSelectOne                   thrpt   40     152.841 ±    1.246  ops/ms
sqlobject.PGSqlObjectV3Benchmark.attach                               thrpt   40      38.234 ±    0.101  ops/ms
sqlobject.PGSqlObjectV3Benchmark.fluentInsertGeneratedKeyBindBean     thrpt   40      12.130 ±    0.121  ops/ms
sqlobject.PGSqlObjectV3Benchmark.fluentInsertGeneratedKeyValues       thrpt   40      12.722 ±    0.094  ops/ms
sqlobject.PGSqlObjectV3Benchmark.fluentSelectOne                      thrpt   40      19.680 ±    0.286  ops/ms
sqlobject.PGSqlObjectV3Benchmark.sqlobjectInsertGeneratedKeyBindBean  thrpt   40      12.379 ±    0.234  ops/ms
sqlobject.PGSqlObjectV3Benchmark.sqlobjectInsertGeneratedKeyValues    thrpt   40      13.135 ±    0.203  ops/ms
sqlobject.PGSqlObjectV3Benchmark.sqlobjectInsertRowCountBindBean      thrpt   40      14.837 ±    0.251  ops/ms
sqlobject.PGSqlObjectV3Benchmark.sqlobjectInsertRowCountValues        thrpt   40      14.841 ±    0.421  ops/ms
sqlobject.PGSqlObjectV3Benchmark.sqlobjectSelectOne                   thrpt   40      18.915 ±    0.190  ops/ms
sqlobject.SqlObjectOperationBenchmark.classRegistered                 thrpt   40       3.473 ±    0.023  ops/ms
sqlobject.SqlObjectOperationBenchmark.jdbiRegistered                  thrpt   40       3.575 ±    0.025  ops/ms
sqlobject.SqlObjectOperationBenchmark.methodRegistered                thrpt   40       3.456 ±    0.024  ops/ms
CaseInsensitiveStringEqualsBenchmark.collatorEqualsCopy                avgt    5      19.665 ±    0.281   ns/op
CaseInsensitiveStringEqualsBenchmark.collatorEqualsOther               avgt    5     459.826 ±   37.153   ns/op
CaseInsensitiveStringEqualsBenchmark.collatorEqualsRandomCase          avgt    5    3218.389 ±   57.404   ns/op
CaseInsensitiveStringEqualsBenchmark.equalsIgnoreCaseCopy              avgt    5      10.963 ±    0.052   ns/op
CaseInsensitiveStringEqualsBenchmark.equalsIgnoreCaseOther             avgt    5       5.535 ±    0.067   ns/op
CaseInsensitiveStringEqualsBenchmark.equalsIgnoreCaseRandomCase        avgt    5      13.270 ±    0.098   ns/op
CaseInsensitiveStringEqualsBenchmark.stringEquals                      avgt    5       3.769 ±    0.050   ns/op
CaseInsensitiveStringEqualsBenchmark.stringNotEquals                   avgt    5       3.037 ±    0.058   ns/op
CaseInsensitiveStringEqualsBenchmark.toLowerCaseEqualsCopy             avgt    5      40.020 ±    0.414   ns/op
CaseInsensitiveStringEqualsBenchmark.toLowerCaseEqualsOther            avgt    5      25.335 ±    0.029   ns/op
CaseInsensitiveStringEqualsBenchmark.toLowerCaseEqualsRandomCase       avgt    5      44.283 ±    0.130   ns/op
ConstructorBenchmark.constructorMhInvoke                               avgt   20       7.023 ±    0.015   ns/op
ConstructorBenchmark.constructorMhInvokeArgs                           avgt   20     119.567 ±    1.698   ns/op
ConstructorBenchmark.constructorMhInvokeExact                          avgt   20       2.750 ±    0.008   ns/op
ConstructorBenchmark.constructorMhInvokeExactAsType                    avgt   20       2.742 ±    0.006   ns/op
ConstructorBenchmark.constructorNonfinalMhInvokeExact                  avgt   20       7.305 ±    0.015   ns/op
ConstructorBenchmark.jcuCheckedCreate                                  avgt   20    1172.895 ±   22.343   ns/op
ConstructorBenchmark.jcuFindInstantiate                                avgt   20      21.321 ±    0.250   ns/op
EnumMapperBenchmark.mapByExactName                                     avgt    5  262803.903 ± 1495.791   ns/op
EnumMapperBenchmark.mapByOrdinal                                       avgt    5  224438.235 ±  585.365   ns/op
EnumMapperBenchmark.mapByRandomCaseName                                avgt    5  313518.257 ± 2739.219   ns/op

@elonazoulay
Copy link
Contributor Author

elonazoulay commented Mar 9, 2024

lmk if you prefer this version or the weak hashmap version (static cache w synchronized weak hashmap). This version caches the method handle and types directly in the instance factory.

@elonazoulay elonazoulay mentioned this pull request Mar 13, 2024
@stevenschlansker
Copy link
Member

Merging #2657 . Thanks!

stevenschlansker added a commit that referenced this pull request Mar 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants