Some performance questions
Lars Kyllingstad
public at kyllingen.NOSPAMnet
Mon Feb 2 06:55:37 PST 2009
Chris Nicholson-Sauls wrote:
> Lars Kyllingstad wrote:
>> I have some functions for which I want to find the nicest possible
>> combination of performance and usability. I have two suggestions as to
>> how they should be defined.
>>
>> "Classic" style:
>>
>> real myFunction(real arg, int someParam, inout real aReturnValue)
>> {
>> declare temporary variables;
>> do some calculations;
>> store a return value in aReturnValue;
>> return main return value;
>> }
>>
>> The user-friendly way, where the function is encapsulated in a class:
>>
>> class MyFunctionWorkspace
>> {
>> declare private temporary variables;
>>
>> real anotherReturnValue;
>>
>> this (int someParam)
>> { ... }
>>
>> real myFunction(real arg)
>> {
>> do some calculations;
>> store a return value in aReturnValue;
>> return main return value;
>> }
>> }
>>
>> I'm sure a lot of people will disagree with me on this, but let me
>> first say why I think the last case is more user-friendly. For one
>> thing, the same class can be used over and over again with the same
>> parameter(s). Also, the user only has to retrieve aReturnValue if it
>> is needed. If there are many such "additional" inout parameters which
>> are seldom needed, it gets tedious to declare variables for them every
>> time the function is called. I could overload the function, but this
>> also has drawbacks if there are several inout parameters with the same
>> type.
>>
>> My questions are:
>>
>> - If I do like in the second example above, and reuse temporary
>> variables instead of allocating them every time the function is
>> called, could this way also give the best performance? (Yes, I know
>> this is bad form...)
>>
>> ...or, if not...
>>
>> - If I (again in the second example) move the temporary variables
>> inside the function, so they are allocated on the stack instead of the
>> heap (?), will this improve or reduce performance?
>>
>> I could write both types of code and test them against each other, but
>> I am planning to use the same style for several different functions in
>> several modules, and want to find the solution which is generally the
>> best one.
>>
>> -Lars
>
>
> If I understand right that your main concern is with parameters that are
> used over and over and over again -- which I can empathize with -- you
> could also look into function currying. Assuming you are using Phobos,
> the module you want to look at is std.bind, usage of which is pretty
> straightforward. Given a function:
>
> real pow (real base, real exp);
>
> You could emulate a square() function via std.bind like so:
>
> square = bind(&pow, _0, 2.0);
> square(42.0); // same as: pow(42.0, 2.0)
>
> If you are using Tango, I'm honestly not sure off the top of my head
> what the relevant module is, but you could always install Tangobos and
> use std.bind just fine.
>
> All that being said, I have no experience with currying functions with
> inout parameters. If my understanding of how std.bind works its magic
> is right, it should be fine. I believe it wraps the call up in a
> structure, which means the actual parameter will be from a field of said
> structure... which, actually, means it could also store state. That in
> itself could be an interesting capability.
>
> -- Chris Nicholson-Sauls
Most of the time I use Tango, but in this particular case I don't want
my code to depend on either library. Also I'm not sure whether the
std.bind functionality is even present in Tango. I could always write
my.own.bind, though.
Your solution is nice from a usability perspective, in that it reuses
function arguments -- possibly even inout ones. From a performance
perspective, however, it carries with it the overhead of an extra
function call, which I'm not sure I want.
-Lars
More information about the Digitalmars-d-learn
mailing list