POV-Ray : Newsgroups : povray.general : Function performance : Re: Function performance Server Time
29 Jul 2024 12:24:14 EDT (-0400)
  Re: Function performance  
From: clipka
Date: 4 Aug 2011 18:00:35
Message: <4e3b1683$1@news.povray.org>
Am 23.07.2011 13:12, schrieb David Given:

> Hmm. Thanks. What's actually used to evaluate the function, then? Is it
> byte-compiled?

It does use a VM, yes.

>> Without knowing the specifics, most likely for your use the best way to
>> eliminate common subexpressions is to use multiple functions and pass
>> the subexpressions as arguments.
>
> Yes, that's what I'm doing --- it's brittle and rather verbose. (A lot
> of my functions take (x, y, z) coordinates, clip them to a sphere, and
> actually do a texture calculation based the clipped value. It's a bit
> painful.)

My favorite solution to such issues is to replace, e.g.,

   #declare F = function(a) { sin(a) + cos(a) + sin(a)*cos(a) }

with

   #declare F_ = function(sina,cosa) { sina + cosa + sina*cosa }
   #declare F  = function(a) { F_(sin(a),cos(a)) }

The idea is to create a helper function where all the multiply-used 
sub-expressions are substituted by parameters, and have a main function 
that computes these sub-expressions and passes them to that helper 
function. I think it's sufficiently easy to read if you use good names 
for the sub-expressions.

I usually use an added underscore for such functions, but you might also 
call them "F2", "F_sub", or whatever fits your taste.

For instance, for your example I might use

   #declare f_normal_x_ = function(x,r,fr) { r * x / fr }
   #declare f_normal_y_ = function(y,r,fr) { r * y / fr }
   #declare f_normal_z_ = function(z,r,fr) { r * z / fr }

   #declare result_ = function(x,y,z,r,fr) { f_bozo(
     f_normal_x_(x,r,fr), f_normal_y_(y,r,fr), f_normal_z_(z,r,fr)
   )}

   #declare result = function(x,y,z,r) { result_(x,y,z,r, f_r(x,y,z)) }

BTW, note that f_normal_x_, f_normal_y_ and f_normal_z_ are actually 
redundant; you could just as well use

   #declare f_normal_ = function(axis,r,fr) { r*axis / fr }
   #declare result_ = function(x,y,z,r,fr) { f_bozo(
     f_normal_(x,r,fr), f_normal_(y,r,fr), f_normal_(z,r,fr)
   )}
   #declare result = function(x,y,z,r) { result_(x,y,z,r, f_r(x,y,z)) }

However, depending on circumstances I might still use separate 
functions, to have a 1:1 mapping between original functions and helper 
functions which might improve legibility.


Not sure if that boils down to the same as your own attempt - I didn't 
try to understand how your set of functions works, as they're indeed not 
excessively easy to read ;-). In my experience, good naming of the 
sub-expression substitution parameters is essential for legibility.


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.