### Code efficiency PV
Paul van Dinther
Thu, Sep 9, 2021 10:05 PM

As I am getting to grips with this strange concept that variables are
really constants and values are assigned at compile time. Besides the fact
it rips my brain in half... What are the considerations for efficient code?

Let's say for argument's sake I write a function that needs to multiply a
list of numbers with the cosine of a given angle.

It could be written like this:
function myfunc1(list=[], angle=0) = [for(l=list) l*cos(angle)];

The programmer in me would balk at that solution and instead write:
function myfunc2(list=[], angle=0) = let(c=cos(angle)) [for(l=list) l*c];

Here I calculate the cosine only once which would be more efficient. But I
am starting to think I am wasting my time with such optimisations because
openSCAD computes values at compile time. So cos(angle) in the first
example is replaced with the calculated result and is therefore no
different from the second "optimized" example.

Can anyone shed some light on this? Preferably with code of pseudo code or
links. I have been looking at the code in various libraries and they
contain some pretty powerful functions. but I have concerns with libraries
such as BOSL that appear rather bloated as every function relies on a chain
of many other custom functions.

What is the cost in execution of unoptimized code? And if code is compiled
every time it runs then I guess the compile time really becomes part of the
run-time.

Oh, I guarantee I will be reading your responses with care but I don't know
how to reply to a thread with this weird 70's email list thing even though
I am 57 ;-)

--
Regards

Paul van Dinther

As I am getting to grips with this strange concept that variables are really constants and values are assigned at compile time. Besides the fact it rips my brain in half... What are the considerations for efficient code? Let's say for argument's sake I write a function that needs to multiply a list of numbers with the cosine of a given angle. It could be written like this: function myfunc1(list=[], angle=0) = [for(l=list) l*cos(angle)]; The programmer in me would balk at that solution and instead write: function myfunc2(list=[], angle=0) = let(c=cos(angle)) [for(l=list) l*c]; Here I calculate the cosine only once which would be more efficient. But I am starting to think I am wasting my time with such optimisations because openSCAD computes values at compile time. So cos(angle) in the first example is replaced with the calculated result and is therefore no different from the second "optimized" example. Can anyone shed some light on this? Preferably with code of pseudo code or links. I have been looking at the code in various libraries and they contain some pretty powerful functions. but I have concerns with libraries such as BOSL that appear rather bloated as every function relies on a chain of many other custom functions. What is the cost in execution of unoptimized code? And if code is compiled every time it runs then I guess the compile time really becomes part of the run-time. Oh, I guarantee I will be reading your responses with care but I don't know how to reply to a thread with this weird 70's email list thing even though I am 57 ;-) -- Regards Paul van Dinther AM
Thu, Sep 9, 2021 10:32 PM

In the vast range of situations, the actual geometrical processing of
OpenSCAD will completely overwhelm the computations you do.  In BOSL2 we
have made efforts to code things with attention to efficiency.  For
example, the bezier producing code is very highly optimized, using matrices
instead of recursion because it was found to be (much) faster.  And we do
routinely test things to find the fastest option.  But there's a trade-off
between optimizing to death and making the code maintainable and friendly
to use (error checking).  So the question to ask: are you trying to do
something and it's too slow?  Only then worry about optimization.

You asked a question about whether trying to pre-compute cos(angle) makes a
difference in the efficiency.  I don't know if it gets recomputed or not.
But I also don't think a few thousand extra computations of cos(angle) is
going to be noticeable, even if it does happen.  But the way to move past
my guess and reach a conclusion is to run your code both ways and observe
the run time that OpenSCAD reports.  Is one way significantly faster?  You
might need to wrap your code in a loop to run it N times for large N in
order to push the run time high enough to tell anything.

On Thu, Sep 9, 2021 at 6:06 PM Paul van Dinther vandinther@gmail.com
wrote:

As I am getting to grips with this strange concept that variables are
really constants and values are assigned at compile time. Besides the fact
it rips my brain in half... What are the considerations for efficient code?

Let's say for argument's sake I write a function that needs to multiply a
list of numbers with the cosine of a given angle.

It could be written like this:
function myfunc1(list=[], angle=0) = [for(l=list) l*cos(angle)];

The programmer in me would balk at that solution and instead write:
function myfunc2(list=[], angle=0) = let(c=cos(angle)) [for(l=list) l*c];

Here I calculate the cosine only once which would be more efficient. But I
am starting to think I am wasting my time with such optimisations because
openSCAD computes values at compile time. So cos(angle) in the first
example is replaced with the calculated result and is therefore no
different from the second "optimized" example.

Can anyone shed some light on this? Preferably with code of pseudo code or
links. I have been looking at the code in various libraries and they
contain some pretty powerful functions. but I have concerns with libraries
such as BOSL that appear rather bloated as every function relies on a chain
of many other custom functions.

What is the cost in execution of unoptimized code? And if code is compiled
every time it runs then I guess the compile time really becomes part of the
run-time.

Oh, I guarantee I will be reading your responses with care but I don't
know how to reply to a thread with this weird 70's email list thing even
though I am 57 ;-)

--
Regards

Paul van Dinther

To unsubscribe send an email to discuss-leave@lists.openscad.org JB
Jordan Brown
Thu, Sep 9, 2021 10:34 PM

On 9/9/2021 3:05 PM, Paul van Dinther wrote:

It could be written like this:
function myfunc1(list=[], angle=0) = [for(l=list) l*cos(angle)];

The programmer in me would balk at that solution and instead write:
function myfunc2(list=[], angle=0) = let(c=cos(angle)) [for(l=list) l*c];

The latter would be slightly more efficient.  But:  an experiment says
that on my (cheap, old) desktop OpenSCAD can do in the general
neighborhood of 250K cosines per second.

but I have concerns with libraries such as BOSL that appear rather
bloated as every function relies on a chain of many other custom
functions.

I suggest that you experiment before you worry.  "Execution time" is
that time between the "Compiling design (CSG Tree generation)" message
and the "Compiling design (CSG Products generation)" message.

And if code is compiled every time it runs then I guess the compile
time really becomes part of the run-time.

Yes.  I would not say so much that it is at compile time, as that the
language has very strict rules about values, and that the product of
executing the program is a CSG tree that is then evaluated by the
geometry engine.

But the real answer is that it is fairly rare that the execution time is
significant compared to the geometry processing time.

Oh, I guarantee I will be reading your responses with care but I don't
know how to reply to a thread with this weird 70's email list thing
even though I am 57 ;-)

Mostly the "reply all" button will do the right thing.

On 9/9/2021 3:05 PM, Paul van Dinther wrote: > It could be written like this: > function myfunc1(list=[], angle=0) = [for(l=list) l*cos(angle)]; > > The programmer in me would balk at that solution and instead write: > function myfunc2(list=[], angle=0) = let(c=cos(angle)) [for(l=list) l*c]; The latter would be slightly more efficient.  But:  an experiment says that on my (cheap, old) desktop OpenSCAD can do in the general neighborhood of 250K cosines per second. > but I have concerns with libraries such as BOSL that appear rather > bloated as every function relies on a chain of many other custom > functions. I suggest that you experiment before you worry.  "Execution time" is that time between the "Compiling design (CSG Tree generation)" message and the "Compiling design (CSG Products generation)" message. > And if code is compiled every time it runs then I guess the compile > time really becomes part of the run-time. Yes.  I would not say so much that it is at compile time, as that the language has very strict rules about values, and that the product of executing the program is a CSG tree that is then evaluated by the geometry engine. But the real answer is that it is fairly rare that the execution time is significant compared to the geometry processing time. > Oh, I guarantee I will be reading your responses with care but I don't > know how to reply to a thread with this weird 70's email list thing > even though I am 57 ;-) Mostly the "reply all" button will do the right thing. FH
Father Horton
Thu, Sep 9, 2021 11:41 PM

You're going to drive yourself nuts unless you study up on functional
languages. I fought battles with XSLT for years before it finally sank in
that XSLT is functional and I needed to look at things in a completely
different way than how I was used to doing it. I had the same struggle with
OpenSCAD, but I realized more quickly that it was functional.

"Variables" that don't vary are a dead giveaway that you're dealing with a
functional language.

On Thu, Sep 9, 2021 at 5:06 PM Paul van Dinther vandinther@gmail.com
wrote:

As I am getting to grips with this strange concept that variables are
really constants and values are assigned at compile time. Besides the fact
it rips my brain in half... What are the considerations for efficient code?

Let's say for argument's sake I write a function that needs to multiply a
list of numbers with the cosine of a given angle.

It could be written like this:
function myfunc1(list=[], angle=0) = [for(l=list) l*cos(angle)];

The programmer in me would balk at that solution and instead write:
function myfunc2(list=[], angle=0) = let(c=cos(angle)) [for(l=list) l*c];

Here I calculate the cosine only once which would be more efficient. But I
am starting to think I am wasting my time with such optimisations because
openSCAD computes values at compile time. So cos(angle) in the first
example is replaced with the calculated result and is therefore no
different from the second "optimized" example.

Can anyone shed some light on this? Preferably with code of pseudo code or
links. I have been looking at the code in various libraries and they
contain some pretty powerful functions. but I have concerns with libraries
such as BOSL that appear rather bloated as every function relies on a chain
of many other custom functions.

What is the cost in execution of unoptimized code? And if code is compiled
every time it runs then I guess the compile time really becomes part of the
run-time.

Oh, I guarantee I will be reading your responses with care but I don't
know how to reply to a thread with this weird 70's email list thing even
though I am 57 ;-)

--
Regards

Paul van Dinther

To unsubscribe send an email to discuss-leave@lists.openscad.org LM
Leonard Martin Struttmann
Fri, Sep 10, 2021 1:10 AM

Very interesting. I hope that you continue to study this and report your
findings here. Also, studying this may reveal additional solutions that
may, indeed, be more efficient.  For the particular example that you
started with, there is also this "solution" which may, or may not be, more
efficient.

a = [ 1, 2, 3, 4, 5 ];
c = cos(45);
echo( a*c );

On Thu, Sep 9, 2021 at 6:42 PM Father Horton fatherhorton@gmail.com wrote:

You're going to drive yourself nuts unless you study up on functional
languages. I fought battles with XSLT for years before it finally sank in
that XSLT is functional and I needed to look at things in a completely
different way than how I was used to doing it. I had the same struggle with
OpenSCAD, but I realized more quickly that it was functional.

"Variables" that don't vary are a dead giveaway that you're dealing with a
functional language.

On Thu, Sep 9, 2021 at 5:06 PM Paul van Dinther vandinther@gmail.com
wrote:

As I am getting to grips with this strange concept that variables are
really constants and values are assigned at compile time. Besides the fact
it rips my brain in half... What are the considerations for efficient code?

Let's say for argument's sake I write a function that needs to multiply a
list of numbers with the cosine of a given angle.

It could be written like this:
function myfunc1(list=[], angle=0) = [for(l=list) l*cos(angle)];

The programmer in me would balk at that solution and instead write:
function myfunc2(list=[], angle=0) = let(c=cos(angle)) [for(l=list) l*c];

Here I calculate the cosine only once which would be more efficient. But
I am starting to think I am wasting my time with such optimisations because
openSCAD computes values at compile time. So cos(angle) in the first
example is replaced with the calculated result and is therefore no
different from the second "optimized" example.

Can anyone shed some light on this? Preferably with code of pseudo code
or links. I have been looking at the code in various libraries and they
contain some pretty powerful functions. but I have concerns with libraries
such as BOSL that appear rather bloated as every function relies on a chain
of many other custom functions.

What is the cost in execution of unoptimized code? And if code is
compiled every time it runs then I guess the compile time really becomes
part of the run-time.

Oh, I guarantee I will be reading your responses with care but I don't
know how to reply to a thread with this weird 70's email list thing even
though I am 57 ;-)

--
Regards

Paul van Dinther