-
Notifications
You must be signed in to change notification settings - Fork 60
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
stdLambda
performance re-visited
#49
Comments
It's difficult to say for sure, it could be due to a number of reasons. Happy for help looking into exactly why. The relevant parts of the code are as follows: Some whatchouts:
If TypeName(Me.oFunctExt) = "Dictionary" Then
If Me.oFunctExt.exists(sFuncName) Then
Dim vInjectedVar As Variant
Call CopyVariant(vInjectedVar, oFunctExt(sFuncName))
If TypeOf vInjectedVar Is stdICallable Then
Call CopyVariant(evaluateFunc, Me.oFunctExt(sFuncName).RunEx(args))
Else
Call CopyVariant(evaluateFunc, vInjectedVar)
End If
Exit Function
End If
End If so that's where i'd check first In general though it's likely because at min-3 stack pops are required (Func symbol, argLength, arg + timeWhileEvaluating); where with standard numerical evaluation only 1 stack pop is required (arg). |
-snip- (Moved by admin as was unrelated to performance) |
Had a discussion with @TarVK a few days ago. He thinks it's not too surprising that these performance issues exist as Recompilation of operations approachAn option would be to search the compiled operation array and detect if any jumps occur. If no jump occurs then there is no need for a stack, and operation set can be compiled to a expression tree similar to that used by Expression / Statement seperation approachAnother option is to seperate what
Expressions don't need a stack so can be evaluated quickly. Ultimately the design would be to have an |
This looks like an easy path to implement the required hot fix. I think that the first proposal will end in an entirely class eval method rewriting. |
stdLambda
PerformanceIt has come to my attention that there exists another library a lot like
stdLambda
, namedclsMathParser
. This library apparently existed since 2004(?!), so totally unsure how this skipped passed my radar! It's not a very intuitive library but essentially functions as follows:This library is, according to my testing, 5x vaster than
stdLambda
. Test set:Comparrison of algorithm
clsMathParser
's stack is pre-populated with values paired with operators. This ultimately means less operations done in VBA side:clsMathParser
splitsx^2+x+2
into 3 operations:ET(0)
= completion opET(1)
=^
prevArg + varX^2
(???)ET(2)
=+
prevArg + varX
ET(3)
=+
0+2
stdLambda
splits$1^2+$1+2
into 7 operationsops(0)
= Arg 1ops(1)
= Push 2ops(2)
= Op Powops(3)
= Arg 1ops(4)
= Op Addops(5)
= Push 2ops(6)
= Op Addops(7)
= CompletionstdLambda
's starts with an empty stack and alocates it with values at runtime. Though we're only copying a few bytes I guess this consumes a lot of time compared to having all that data pre-prepared. A pre-populated stack is something we should likely look into.stdLambda
used to be copying argument location from a string at runtime, which is slow! I changed this and it saves some 30µs per operation. Fixed in 2a9b2e0clsMathParser
isn't stand alone sadly, and doesn't provide object access.stdLambda
does provide object access and is standalone by comparrison (although technically requiresstdICallable
- easily removed by comparrison)clsMathParser
uses aByRef
param for the return type. That shaves off some time, although not significant in my tests. But still clever fosho :)The text was updated successfully, but these errors were encountered: