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

Optimize interpreter speed (umbrella issue) #91

Closed
2 of 5 tasks
benhoyt opened this issue Jan 23, 2022 · 6 comments
Closed
2 of 5 tasks

Optimize interpreter speed (umbrella issue) #91

benhoyt opened this issue Jan 23, 2022 · 6 comments

Comments

@benhoyt
Copy link
Owner

benhoyt commented Jan 23, 2022

I've done a bunch of performance work already, but we could always use more:

@jfesler
Copy link

jfesler commented Jan 23, 2022

I have no right to ask for this, particularly since I can't contribute code (sigh). But I'll ask anyways in case you find a reasonable way to do it, and can expose it.

It would be awesome if we could init, compile, and get back a handle that could economically be reused with new inputs and get new outputs. The use case would be something similar to an array of json objects, where normal awk semantics don't quite work. What I do now is re-init entirely, once per record, with some local sync.pool optimizations; coupled with user defined functions for fetching data from "the" record by field name.

@benhoyt
Copy link
Owner Author

benhoyt commented Jan 23, 2022

@jfesler You can always ask! :-) Re "I can't contribute code" -- is that a technical issue? or that you don't know Go or aren't a programmer? Just want to make sure GoAWK is open to external contributions as expected.

In any case, I think this is a good idea. I'll spend some time thinking about a good API (I'll need to keep the existing ExecProgram for backwards compatibility), but once I've done that it shouldn't be that hard to code it up. If you have any concrete API suggestions, let me know.

Do you have a link to your existing code, or is it private?

@benhoyt
Copy link
Owner Author

benhoyt commented Jan 23, 2022

Looking at this a bit more closely, I guess we already have a "handle" of sorts, the parsed *parser.Program. Presumably that's not quite performant enough for your use case, as interp.ExecProgram does a bunch of allocation (for example)? Is it mainly those dozen or so make() calls (allocations) that you want to avoid?

There will have to be some initialization / resetting of state, but ideally we could avoid (most of?) the allocations. Something like this?

// do this once
program, err := parser.ParseProgram(src, parserConfig)
if err != nil { /* handle error */ }
interpreter, err := interp.New(program) // would return a new exported interp.Interp
if err != nil { /* handle error */ }

// do this as many times as necessary
status, err := interpreter.Execute(interpConfig)
if err != nil { /* handle error */ }

@jfesler
Copy link

jfesler commented Jan 23, 2022

My inability to contribute is a policy issue :-(

And, yes, that looks lovely, if we can get the per .Execute initialization down. When I last looked at this, it was mostly a matter of either resetting existing vars (if not nil); and/or using sync.Pool to reuse allocations. Allocations are a big deal.

@benhoyt
Copy link
Owner Author

benhoyt commented Jan 23, 2022

@jfesler Excellent. I've opened #94 to track that explicitly. No promises as to when I can get to it (I'm trying to finish the bytecode work right now), but hopefully in a few weeks. Obviously feel free to fork it in the meantime!

@benhoyt benhoyt changed the title Optimize interpreter speed Optimize interpreter speed (umbrella issue) Jan 24, 2022
raff added a commit to raff/goawk that referenced this issue Feb 3, 2022
Added a ConcatN opcode. Could have used MultiIndex opcode (I tried and it works
as is) but "concat" should not be using a separator.
@benhoyt
Copy link
Owner Author

benhoyt commented May 18, 2022

I'm going to close this umbrella issue -- we can open specific issues as needed. Plus, the regexp issue is kind of beyond our control (though I'm glad some folks are working on that over at golang/go).

@benhoyt benhoyt closed this as completed May 18, 2022
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

2 participants