January 03, 2018
On Wed, Jan 03, 2018 at 07:02:28AM +0000, Tim Hsu via Digitalmars-d-learn wrote:
> On Tuesday, 2 January 2018 at 22:49:20 UTC, Adam D. Ruppe wrote:
> > On Tuesday, 2 January 2018 at 22:17:14 UTC, Johan Engelen wrote:
> > > Pass the Vector3f by value.
> > 
> > This is very frequently the correct answer to these questions! Never assume ref is faster if speed matters - it may not be.
> 
> However speed really matters for me.

That's why you need to use a profiler to find out where the hotspots are. It may not be where you think it is.


> I am writing a path tracing program.  Ray will be constructed million of times during computation.  And will be passed to functions to test intersection billion of times.  After Reading comments here, it seems ray will be passed by value to the intersection testing function. I am not sure if ray is small enough to be passed by value. It needs some experiment.

With modern CPUs with advanced caching, it may not always be obvious whether passing by value or passing by reference is better.  Always use a profiler to be sure.


T

-- 
If blunt statements had a point, they wouldn't be blunt...
January 03, 2018
On Tuesday, 2 January 2018 at 23:27:22 UTC, H. S. Teoh wrote:
>
> When it comes to optimization, there are 3 rules: profile, profile, profile.  I used to heavily hand-"optimize" my code a lot (I come from a strong C/C++ background -- premature optimization seems to be a common malady among us in that crowd).

That's why I always tell that C++ is premature optimization oriented programming, aka as POOP.
January 03, 2018
On 01/03/2018 10:40 AM, Patrick Schluter wrote:
> On Tuesday, 2 January 2018 at 23:27:22 UTC, H. S. Teoh wrote:
>>
>> When it comes to optimization, there are 3 rules: profile, profile,
>> profile.  I used to heavily hand-"optimize" my code a lot (I come from
>> a strong C/C++ background -- premature optimization seems to be a
>> common malady among us in that crowd).
>
> That's why I always tell that C++ is premature optimization oriented
> programming, aka as POOP.

In my earlier C++ days I've embarrassed myself by insisting that strings should be passed by reference for performance reasons. (No, I had not profiled.) Then I learned more and always returned vectors (and maps) by value from producer functions:

vector<int> makeInts(some param) {
    // ...
}

That's how it should be! :)

I used the same function when interviewing candidates (apologies to all; I don't remember good things about my interviewing other people; I hope I will never interview people like that anymore). They would invariably write a function something like this:

void makeInts(vector<int> & result, some param) {
    // ...
}

And that's wrong because there are the big questions of what do you require or do with the reference parameter 'result'? Would you clear it first? If not, shouldn't the function be named appendInts? If you cleared it upfront, would you still be happy if an exception was thrown inside the function, etc.

That's why I like producer functions that return values:

vector<int> makeInts(some param) {
    // ...
}

And if they can be 'pure', D allows them to be used to initialize immutable variables as well. Pretty cool! :)

Ali

January 03, 2018
On 2018-01-03 08:02, Tim Hsu wrote:
>  It needs some experiment.

This is the correct answer. Never assume anything about performance before having tested it.

-- 
/Jacob Carlborg
January 28, 2018
Am Wed, 3 Jan 2018 10:57:13 -0800
schrieb Ali Çehreli <acehreli@yahoo.com>:

> On 01/03/2018 10:40 AM, Patrick Schluter wrote:
>  > On Tuesday, 2 January 2018 at 23:27:22 UTC, H. S. Teoh wrote:
>  >>
>  >> When it comes to optimization, there are 3 rules: profile, profile,
>  >> profile.  I used to heavily hand-"optimize" my code a lot (I come from
>  >> a strong C/C++ background -- premature optimization seems to be a
>  >> common malady among us in that crowd).
>  >
>  > That's why I always tell that C++ is premature optimization oriented
>  > programming, aka as POOP.
> 
> […]
>
> That's why I like producer functions that return values:
> 
> vector<int> makeInts(some param) {
>      // ...
> }
> 
> And if they can be 'pure', D allows them to be used to initialize immutable variables as well. Pretty cool! :)
> 
> Ali

May I add, this is also optimal performance-wise. The result variable will be allocated on the caller stack and the callee writes directly to it. So even POOPs like me, do it.

-- 
Marco

March 15, 2018
On Tuesday, 2 January 2018 at 18:21:13 UTC, Tim Hsu wrote:
> I am creating Vector3 structure. I use struct to avoid GC. However, struct will be copied when passed as parameter to function
>
>
> struct Ray {
>     Vector3f origin;
>     Vector3f dir;
>
>     @nogc @system
>     this(Vector3f *origin, Vector3f *dir) {
>         this.origin = *origin;
>         this.dir = *dir;
>     }
> }
>
> How can I pass struct more efficiently?

This isn't a question for you. it's a question for the compiler, let the compiler do its thing. Stick in a -O3 if you are using GCC or LDC and build in release more not debug mode. Make sure that the compiler can see the source code of the implementation of the constructor wherever it is used and it should just be inclined away to nonexistence. Your constructor should not even exist, if it is then you are looking at a false picture or a mistake where optimisation has been turned off for the sake of easy source-level debugging.

Post up the assembler language output for a routine where this code is used in some critical situation, and then we can help make sure that the code _generation_ is optimal.

I reiterate, unless something is badly wrong or you are seeing a red herring, no 'call' to the constructor code should even exist in the cases where it is actually 'called'. You may well see a useless copy of the constructor code because the compilers seem to generate such even though it is never called ans so is a waste of space. The compiler will analyse the constructor's instructions and just copy-and-paste them as assignment statements with that then getting thoroughly optimised down into something which may just be a memory write or a register-register copy that costs zero.

If you post up snippets of generated asm then U will be delighted to take a look.
March 15, 2018
On Thursday, 15 March 2018 at 23:14:14 UTC, Cecil Ward wrote:
> On Tuesday, 2 January 2018 at 18:21:13 UTC, Tim Hsu wrote:
>> [...]
>
> U

or even 'I' will be delighted to take a look.
March 15, 2018
On Thursday, 15 March 2018 at 23:15:47 UTC, Cecil Ward wrote:
> On Thursday, 15 March 2018 at 23:14:14 UTC, Cecil Ward wrote:
>> On Tuesday, 2 January 2018 at 18:21:13 UTC, Tim Hsu wrote:
>>> [...]
>>
>> U
>
> or even 'I' will be delighted to take a look.

Also link time optimisation and whole program optimisation might be your friends if you are having problems because module boundaries mean that the compiler cannot expand the source code of the constructor implementation to inline it and fully optimise it away to nothing.

You certainly should have no problems if the code that uses the struct can see the struct definition's actual source text directly.

1 2
Next ›   Last »