-
Notifications
You must be signed in to change notification settings - Fork 75
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
Annotations.labelOf is catastrophically slow #288
Comments
Wow, that's indeed catastrophically slow, thank you for investigating! |
We now generate all of the case classes that represent elements in our schema (as well as our ShiftLeftSecurity/tinkergraph-gremlin vertex/edge implementations and much of the machinery that's needed for all of that such as files enumerating constants). The constants we keep for labels happen to be resolved via labelOf instead of used in the labelOf annotation. Here is a example CC we use in test:
Long story short, this no longer affects. It may affect others, so it's probably worth leaving a release note if you change the behavior if you don't go with one of @timw 's other suggestions. |
Regarding @timw 's analysis, everything he mentions seems sound. |
revert PR: #289 |
#253 introduced in
Annotations.labelOf[T]
an implementation of extracting the@label
value that worked for non literal values (e.g.@label(SomeClass.LABEL)
as well as literal values (e.g.@label("vert")
).This implementation, unfortunately, is terribly slow (to the point I noticed a single invocation of the method slowed a unit test by over a second, which got me to investigating).
The
labelOf
implementation usesToolbox.eval
, which invokes the back-end of the Scala compiler.This implementation averages about 65ms per invocation on my dev system (an i7 MBP).
An implementation that only uses the introspection APIs is 1000 times quicker (something like 60 micro seconds):
This is in essence what the
Marshallable
materialization macro and the original code does.The problem is obviously that this regresses the ability to retrieve a non literal value.
A macro based implementation is 1,000,000 times quicker:
(This is keeping the
labelOf[T]: Option[label]
contract - in actual use, we only need the String value).Unfortunately this has another problem, in that it needs a
WeakTypeTag
of a real class type, which can only be produced at the time of invocation.e.g. Calling
Annotations.labelOf[MyType]
will work, but notAnnotations.labelOf[T]
as we see inGremlinScala.hasLabel[CC]
. TheWeakTypeTag
that is passed throughhasLabel
isn't compatible with the implicit macro contextWeakTypeTag
required by the macro.At this point I'm not sure what the best resolution is (otherwise I'd have PRed this):
WeakTypeTag
so it can be invoked indirectly through methods likehasLabel
.GremlinScala
andScalaGraph
could change to take an implicitLabelExtractor
implementation materialized by the macro (i.e. instead of the implicit WeakTypeTag evidence provided by the type context bound now). I have this prototyped, and it works.I'm happy to put together a PR if there's a consensus on a solution, but I can't think of anything at the moment that doesn't break API and/or ABI.
The text was updated successfully, but these errors were encountered: