esprima-dotnet
esprima-dotnet copied to clipboard
Use System.Span
Opening for tracking. My masterpiece where Slice tries to match common keywords will come much simpler. This will affect a lot of public API by having ReadOnlySpan
I'm leaning towards having custom TextSpan like Parlot has and then allowing span-based operations via it's Span
property.
Span can be used where the methods take it as input, like number parsing, but there's so much performance overhead trying to handle Memory<T> and span against backing string script.
@Xicy I might have some prototype in some branch, I probably need to check if it's any good starting point and how far away from current main...
I'm leaning towards having custom TextSpan like Parlot has and then allowing span-based operations via it's Span property.
Isn't TextSpan
practically the same as ReadOnlyMemory<char>
? Though I don't know if the underlying object needs to be accessed. If so, then there's another built in type, StringSegment
in the framework.
Hmm, didn't know about StringSegment
, thanks for sharing. It's a bit heavy to bring a dependency package just for that though. What I remember from Memory<T>, it brought quite the overhead, might have used it wrong too tough.
It's safe to say that original string is always around and ok to keep in memory for the lifetime of the Program (Script/Module), needs a lightweight way to access it. Memory/Span approach becomes problematic when the value needs to be stored as dictionary key (which Jint does a lot), span cannot be used as a key - TextSpan
/StringSegment
can. From Jint's perspective having to do .ToString()
to gain usable key would make change meaningless (Memory/Span).
What I remember from Memory, it brought quite the overhead, might have used it wrong too tough.
I'm also not an expert on (ReadOnly)Memory<T>
but at first glance it just stores the same info (object, index, length) and being an ordinary struct, it can be used as dictionary key as well. Converting it to a (ReadOnly)Span<T>
looks like a bit complicated though. Maybe that's where the overhead come from?
One further thing I'm aware of: Span<T>
and co. have worse performance on .NET Framework than on .NET Core as they're implemented differently. Here's some additional resource on the topic. (Disclaimer: despite the similar name, I'm not the author of the article 😄)
EDIT: I consistently used Memory<T>
in my comments but our use case probably would need ReadOnlyMemory<T>
instead.
I've tested this with StringSegment and memory benefits are very little as long as Token instances dominate allocations.
In the light of work done recently we can consider this done, right?
Indeed!