-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Optimise Kleisli with specialized Function1
implementation
#4211
Conversation
Thought of a better way to do this, by specializing |
@@ -204,7 +209,7 @@ sealed private[data] trait KleisliFunctions { | |||
* }}} | |||
*/ | |||
def liftF[F[_], A, B](x: F[B]): Kleisli[F, A, B] = | |||
Kleisli(_ => x) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we can find other places in cats where we have _ => x
and replace with StrictConstFunction1
profitably.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe! But see #4211 (comment)
The benchmarks for this implementation (added to the bottom of the PR description) aren't actually as good as the one from b576136 that specialised |
On further thought, I don't think we can so blithely assume referential transparency as this PR does - for example we provide a Unfortunately I don't have time to think this through just now. Any thoughts welcomed! Edit: |
Discussion on referential transparency taking place on Discord at https://discord.com/channels/632277896739946517/633329569402978313/978609454465564752 - the consensus seems to be that we can assume RT and there are no gurantees about what happens when that assumption is violated. |
Re-opening this for review - there's probably scope for some further optimisation but the benefits as they stand are pretty clear. |
Kleisli.liftF
Function1
implementation
Adds an implementation of Kleisli that directly wraps a givenAdds aF[B]
rather than lifting it into a function.StrictConstFunction1
type to optimise Kleisli lifted from effectful values. Intended to improve performance of tagless final algebras running in Kleisli. This is borne out by results of cats-effect deep bind benchmark, lifted to Kleisli in the obvious way - throughput onasync
increases by about 65%, ondelay
by about 54%, and onpure
by about 12%.cats-effect deep bind: IO
jmh:run -i 10 -wi 10 -f 2 -t 1 cats.effect.benchmarks.DeepBindBenchmark
cats-effect deep bind: Kleisli (before):
jmh:run -i 5 -wi 5 -f 1 -t 1 cats.effect.benchmarks.DeepBindBenchmark
cats-effect deep bind: Kleisli (first implementation in this PR):
jmh:run -i 5 -wi 5 -f 1 -t 1 cats.effect.benchmarks.DeepBindBenchmark
cats-effect deep bind: Kleisli (current implementation in this PR, with
StrictConstFunction1
):jmh:run -i 5 -wi 5 -f 1 -t 1 cats.effect.benchmarks.DeepBindBenchmark