-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Library variables recomputed on each module call #782
Comments
This is not intended - top-level expressions in use'd libraries should only be evaluated once. I've been setting up some larger-scale test scripts, mostly for performance testing, but they're also useful for regression testing across OpenSCAD releases. Perhaps I should extend those a bit. Right now it only works with customizable designs published on thingiverse, but that could be lifted by massaging the scripts a bit: https://github.com/openscad/statistics-scripts. The large initial job is to collect public URLs for published OpenSCAD designs. |
I stumbled across this recently and was surprised to learn about this old bug report. The run time implications of this bug are quite serious: in a recent test I improved my code run time from 10.5 minutes to 5 seconds by commenting out high level examples in a library file. |
Yes I moved some test code from a library module into separate test file that used the library and got a speed up. |
I prepared a testcase to help benchmark and illustrate the behavior of this recomputing issue: slow.scad:
slowused.scad:
This testcase was carefully constructed with the logic needed to misbehave identically in the master branch and in recent releases, separating this remaining performance behavior from the recent changes, in case comparisons across versions are desired to resolve this. Commenting the use and uncommenting the include produces the correct one-pass behavior: For include:
However, currently for the use case:
Increase the value "howslow = 25;" in the used file if you want to see how slow the function calls to the "add one" function can get from the top-level reprocessing in the use case. I started my testing with howslow = 10000; but this bug has such an impact that one has to turn it down quite a bit to get a tolerably usable testcase. |
Here is a simplified synthetic case to illustrate the problem:
_Snippet 1_
_Snippet 2_
If these two snippets are placed in the same file, everything executes as expected. The expensive_computation() is performed once and the cheap
interpolate
call does the work as intended. Now to the problem: if we instead put Snippet 1 in its own library:lib.scad
, and call it like thisthe expensive_computation() call will suddenly be performed 1000 times – causing a dramatic slowdown.
While this could all be as intended (there is a fringe use-case, see below), I think it is more likely an unintended consequence of doing what was easiest – avoiding having to find a way to store the global context of each
use
d file, instead recomputing it at each module instantiation and function call.Fixing the issue is easy, but I've not attached a patch as there is a remote chance that the behavior is intended, and because there is also a remote chance of this breaking / changing the behavior of some existing code that could be relying on this.
Here is the most likely (although very contrived) theoretical scenario I've come up with that would change behavior by fixing this:
_lib.scad_
And used:
The fix would make m() generate a circle with 25 sides (default $fn*5).
That behavior is a bit inconsistent, as changing
use
->include
already today makes the circle get 25 sides.Is this behavior intended, and are there any more reasonable use-cases?
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
The text was updated successfully, but these errors were encountered: