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

An ode to borer, or: Please add support for scala-native #633

Open
phdoerfler opened this issue Apr 30, 2023 · 13 comments
Open

An ode to borer, or: Please add support for scala-native #633

phdoerfler opened this issue Apr 30, 2023 · 13 comments

Comments

@phdoerfler
Copy link

tl;dr: doing REST with scala-native is more feasable than ever, yet borer is not available for scala-native. Is there a chance for this to change?

With http4s-curl there exists a non-blocking http backend for scala-native and rumor has it the next version of scala-native will bringt support for multiple threads. Exciting times!
And whilst there are indeed a number of json libraries published for scala-native, e.g., circe, upickle and jsoniter, my favourite json library of them all is notably absent. Please publish borer for scala-native. You shall have my eternal grattitude and this ode to borer:

Oh Borer, thou art a JSON library so fine,
With elegance and speed that are truly divine.
In Scala code, thou art a gem to behold,
Parsing JSON with ease, so quick and so bold.

Thy syntax is simple, yet powerful and strong,
Converting JSON to case classes, all along.
With thy support for JSON Schema and more,
Thou art a library that developers adore.

Oh Borer, how sad it is to say,
That thou art not available for Scala Native today.
For those who seek performance in their apps,
Thy absence in Scala Native may cause some gaps.

But fear not, dear Borer, for thou art still great,
A shining star in the Scala ecosystem's fate.
May thou continue to thrive and grow,
And bring joy to developers, high and low.

So here's to Borer, the JSON library so bright,
May it continue to shine with all its might.
And though it may not be available for Scala Native,
We still cherish thee, oh Borer, for all that thou give.

@sirthias
Copy link
Owner

Thank you, Philipp, for the praise and this ticket!
I haven't used scala-native myself yet and therefore feel a bit out of touch with its idiosyncrasies, of which I'm sure to be some. Honest question: Have you tried using Graal's Native Image support instead?
With all I've read I think I'd go down that route first before turning to scala-native, but since I haven't spent any time with either solution there might be big gaps in my knowledge here.
Do you think scala-native has a future given the big strides with which Graal Native Image appears to evolve?

And one more question: Can you show the prompt for the "ode"? ;-)

@mushtaq
Copy link
Contributor

mushtaq commented May 1, 2023

With thy support for JSON Schema and more,
Thou art a library that developers adore.

JSON Schema support?
Is this real or the poet is hallucinating?

@sirthias
Copy link
Owner

sirthias commented May 1, 2023

The latter... :-)
The poet is infamous for certain kind of hallucinations, which doesn't much reduce the impressiveness of the feat as such however.

@phdoerfler
Copy link
Author

Glad you liked it :) Here you go:

write an ode to borer, an elegant and fast json library for scala, mentioning the regret that it is not available for scala-native

@phdoerfler
Copy link
Author

About native image vs. scala-native: Yes, I have used both native image and scala-native. My experience is mostly in line with this article:
https://medium.com/virtuslab/revisiting-scala-native-performance-67029089f241

I like the idea of scala-native targeting LLVM and producing faster and leaner binaries. This might look very different if you have the enterprise version of GraalVM where you can do profile guided optimization in native image, however. Alas, I do not.

In addition, typelevel has put a lot of effort into publishing their libraries for all platforms including scala-native. I trust that they are seeing potential in using scala-native over native image. If you want to know more, I can recommend this blog post:
https://typelevel.org/blog/2022/09/19/typelevel-native.html
In particular, have a look at the section "What's next and how can I get involved?". I especially like http4s-grpc
and the WIP scala-native runtime for AWS lambda. That sounds really exciting to me.

My hope is that since borer is already being published for Scala.js, publishing it for scala-native might be relatively low effort. I have never published anything for scala-native, so admittedly that hope is not based on much. I can only tell you that on a Mac it is very easy to use scala-native due to the availability of LLVM.

@sirthias
Copy link
Owner

Ok, Philipp, thank you for this nice writeup!
It looks like scala-native really does have an edge over the alternative in some aspects.
I'm curious as to how things will play out.

There is one thing that I'm not sure about yet:
borer's nice performance on the JVM depends to a large extend on its relying on sun.misc.Unsafe for reading Ints and Longs directly from byte arrays. This allows for borer's SWAR code (SIMD Within A Register) to really shine.
If borer has no access on sun.misc.Unsafe (as on scala.js) for example it'll still work but fall back to a much slower byte-by-byte parsing approach.

From a quick glance sun.misc.Unsafe isn't directly available on scala-native, so some additional work would be required to achieve the "direct reading" approach that's vital for good parsing perf.
I'm sure it's possible though, since "low-level" shouldn't necessarily be a problem for scala-native, but probably requires a bit more work than a simple change to the build setup, unfortunately...

@phdoerfler
Copy link
Author

Thanks for this interesting analysis! That does sound like a bit of a predicament, indeed. It seems that jsoniter-scala, which is available for scala-native, ran into a similar issue: plokhotnyuk/jsoniter-scala#94. I haven't found anything similar in circe even though it is also available on scala-native but I only looked for a brief moment.
While I haven't found anything on SWAR, there is at least an issue for supporting SIMD: scala-native/scala-native#37. So for the time being it looks like it is a bit early to hope for general SIMD support.

I am sure this can be solved, though. As you already pointed out, going low-level with scala-native is what it's made for. Satisfactory performance might already be achievable through ordinary bit manipulation. After all, a UTF-8 encoded '1' (= 110001) is only a & 0x0F away from an integer 1 (dito for 0 to 9 of course). And once vectorization is available, this should be easy to write in SIMD or maybe SWAR.

In any case, I'd welcome borer for native even if it had to use a fallback or this simple bit masking for the time being.

@sirthias
Copy link
Owner

borer doesn't really need any SIMD support from the platform.
64 bit integer arithmetic is all that's required. (See here for a few pointers: https://twitter.com/sirthias/status/1202530876946599937)
But, it needs to be able to read raw Ints and Longs directly from a byte array.
I'm sure that there's a solution to do that with scala-native.

It's just that I don't have time right now to dig into this matter.

Do you need borer for its JSON or its CBOR capabilities?

@phdoerfler
Copy link
Author

I see, thanks for the explanation. Regarding urgency: It’s more of a want than a need. Until borer is released for native there are the two aforementioned JSON libraries. And whilst I would like to experiment with CBOR, that is by no means urgent. In the unlikely case that I will find myself with too much time at my hands I might try what happens when borer is built for native and report back but I wouldn’t count on this happening anytime soon.

@windymelt
Copy link

+1 for Native CBOR library. If we can use Borer on Scala native, we can build agile and type-safe rigid utility that uses binary format. Using Scala CLI, we have been able to build native tool easier!

@sirthias
Copy link
Owner

My points above about the (few) sun.misc.Unsafe calls that borer relies on for efficient parsing still hold.
If you @windymelt have any pointers (or contributions) about how to best read Ints and Longs directly from an index of a byte array on scala-native, I'd be happy to look into integrating it...

@plokhotnyuk
Copy link
Contributor

Probably you can do it like in this amazing hack contributed by @armanbilge

@sirthias
Copy link
Owner

Nice, @plokhotnyuk, thank you for the pointer!
This looks exactly as I was imagining it to be implementable on scala-native.
👍

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

No branches or pull requests

5 participants