Skip to content

How to use sjsonnet as a library with cached parsings? #405

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

Open
artpaym opened this issue May 21, 2025 · 7 comments
Open

How to use sjsonnet as a library with cached parsings? #405

artpaym opened this issue May 21, 2025 · 7 comments

Comments

@artpaym
Copy link

artpaym commented May 21, 2025

Is it possible with sjsonnet to parse source jsonnet files once, and then only trigger evaluations providing different input arguments?

If yes, how?

Readme mentions some possibility around it but I can't understand how to make it work, especially from Java. From readme I've seen the following call example, but as I understand it would parse jsonnet file every time whenever I make this call, and new DefaultParseCache expression kind of hints that also:

// Java
sjsonnet.SjsonnetMain.main0(
    new String[]{"foo.jsonnet"},
    new DefaultParseCache,
    System.in,
    System.out,
    System.err,
    os.package$.MODULE$.pwd(),
    scala.None$.empty()
);

Assumption is that it would be much more faster than doing full call every time, because I feel the parsing steps takes the most time. Use case - a Java web app triggering the same mappings (the same file) on each HTTP request just with different arguments.

Would be nice if an answer to that ticket could also result into corresponding readme update.

@He-Pin
Copy link
Contributor

He-Pin commented May 22, 2025

@artpaym You can take a look at the usage of new Interpreter(...) and then you will get the idea of how to use if with your own parse cache.

If @stephenamar-db thinks a sjsonnet4j module is ok, I can contribute that. @artpaym So you need to create an interpreter with the new Interpreter and then use it.

@stephenamar-db
Copy link
Collaborator

I'm pretty sure the parsing phase is the fast part. The evaluation and materialization are where things get slow

@He-Pin
Copy link
Contributor

He-Pin commented May 22, 2025

That's true, @artpaym. You can take a look at the code inside sjsonnet.SjsonnetMain.main0 and wrap the parse cache with caffeine cache (thread safe), but actually, just as @stephenamar-db just said, the parsing is pretty fast.

@artpaym
Copy link
Author

artpaym commented May 22, 2025

Maybe "parsing" isn't a correct term. I don't know all the details of sjsonnet. In other words, for example, if some file takes 100ms to process (with native sjsonnet, for example), is there anything I can do when using an embedded sjsonnet to speed it up? What speed up percentage approximately I could expect?

I'm asking because afaik I noticed in jrsonnet the jrsonnet_evaluator::apply_tla takes very fast compared to all other structure preparations. But afaik jrsonnet doesn't allow calling it multiple times, because structures aren't thread safe. So I was wondering how it looks like in sjsonnet.

@CertainLach
Copy link

CertainLach commented May 22, 2025

But afaik jrsonnet doesn't allow calling it multiple times

You can call jrsonnet as many times as you want, but you need to evaluate jsonnet file once per thread before you start calling functions from it.

You are talking about partial evaluation, where your code is being parsed into sjsonnet.Expr, and then evaluated into a function sjsonnet.Val

Then you want to apply (call) this function multiple times with different arguments, and pass resulting Vals to sjsonnet.Materializer (Or use different means to convert this value into wanted data structures)

@He-Pin
Copy link
Contributor

He-Pin commented May 22, 2025

@artpaym the needed modification is done in sjsonnet, we are using it in Spring Java app.

Jrsonnet is fast too.

@He-Pin
Copy link
Contributor

He-Pin commented May 22, 2025

@artpaym You need to create the interpreter every time, and because you are passing Expr to the interpreter, maybe you can cache the ExternalVariables too, so :

  1. the jsonnet script
  2. the external variables

But it's the evaluation which is slow.

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

4 participants