-
-
Notifications
You must be signed in to change notification settings - Fork 84
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
Comments
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. |
@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 Do you have a link to your existing code, or is it private? |
Looking at this a bit more closely, I guess we already have a "handle" of sorts, the parsed 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 */ } |
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. |
Added a ConcatN opcode. Could have used MultiIndex opcode (I tried and it works as is) but "concat" should not be using a separator.
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). |
I've done a bunch of performance work already, but we could always use more:
interp.push
is slow, particularly the append check -- can we avoid somehow?CONCAT(a,CONCAT(b,c))
etc toCONCAT(a, b, c)
to avoid allocations/copying. Done by @raff in Optimize CONCAT(CONCAT(a, b), c) #99 -- thanks!The text was updated successfully, but these errors were encountered: