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

Avoid interface method dispatches for iterables in Validator #2499

Merged
merged 1 commit into from
Jan 2, 2025

Conversation

kyri-petrou
Copy link
Collaborator

@kyri-petrou kyri-petrou commented Dec 31, 2024

While looking at some profiles, I noticed a lot of itable stubs in Caliban's Validator. Most of those came from methods such as nonEmpty and toList on classes that don't override them. In addition, in Scala 3 there was a fair bit of overhead when using foreach because it is not inlined (unlike Scala 2).

In this PR, we:

  • substitute calls to nonEmpty with either v ne Nil for Lists and !v.isEmpty for other iterables, and in some cases avoid method calls altogether when we know the iterable is empty.
  • Add a package-private foreachOne method as a substitute of foreach for lists (which we heavily use in Validator). In Scala 3 this is an inlined while loop, whereas in Scala 2 we simply proxy to foreach (which the compiler inlines)
  • Avoid invocation of unapply methods wherever possible especially in cases that we are not using all of the arguments of a case class

This results in a rather noticeably performance improvement (for Scala 3, haven't tested for Scala 2) especially when validating small queries (up to 50% improvement)

series/2.x:

[info] Benchmark                                        Mode  Cnt        Score        Error  Units
[info] ValidationBenchmark.deep                        thrpt   10  1767580.000 ±   8513.908  ops/s
[info] ValidationBenchmark.introspection               thrpt   10   161401.839 ±  11599.050  ops/s
[info] ValidationBenchmark.multifield                  thrpt   10  2143755.893 ±  35898.045  ops/s
[info] ValidationBenchmark.simple                      thrpt   10  4089052.472 ±  60659.943  ops/s

PR:

[info] Benchmark                                        Mode  Cnt        Score        Error  Units
[info] ValidationBenchmark.deep                        thrpt   10  2578415.376 ±  34212.116  ops/s
[info] ValidationBenchmark.introspection               thrpt   10   168605.760 ±   3666.029  ops/s
[info] ValidationBenchmark.multifield                  thrpt   10  2888155.836 ±  12638.780  ops/s
[info] ValidationBenchmark.simple                      thrpt   10  6226946.771 ±  88354.757  ops/s

@kyri-petrou kyri-petrou merged commit d17c971 into series/2.x Jan 2, 2025
10 checks passed
@kyri-petrou kyri-petrou deleted the optimize-itable-stubs-validator branch January 2, 2025 09:27
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

Successfully merging this pull request may close these issues.

2 participants