D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 5787 - Invisible multiple function calls when using .tupleof
Summary: Invisible multiple function calls when using .tupleof
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other Windows
: P2 normal
Assignee: No Owner
URL:
Keywords: performance
Depends on:
Blocks:
 
Reported: 2011-03-27 08:10 UTC by bearophile_hugs
Modified: 2012-04-23 10:40 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2011-03-27 08:10:09 UTC
Through profiling I have found a performance problem in my code. I have later reduced the case and created this demo code:


import std.typecons: tuple;
import std.c.stdio: printf;
auto foo() {
    printf("foo\n");
    return tuple(1, 2);
}
void main() {
    foreach (x; foo().tupleof)
        printf("%d\n", x);
}


Its output, DMD 2.052:

foo
1
foo
2

In my code foo() was an expensive computation.
In my opinion in this situation foo() needs to be computed only once (or I'd like some other solution to avoid this invisible multiple calls, like some kind of error, etc).
Comment 1 bearophile_hugs 2011-03-28 09:49:05 UTC
Kai Meyer has shown this related program:


import std.typecons: tuple;
import std.c.stdio: printf;
auto foo() {
    printf("foo\n");
    return tuple(1, 2);
}
void main() {
    auto f2 = foo().tupleof;
}


Its output:

foo
foo

So maybe the problem seems isn't caused by the static foreach.
Comment 2 kennytm 2011-03-28 12:02:32 UTC
The problem is in .tupleof, where (expr).tupleof is rewritten to TypeTuple!((expr).field0, (expr).field1, (expr).field2, ...) even if expr have side effect, e.g.

-----------

import std.c.stdio : printf;

struct S {
    int x;
    int y;
}

void main() {
    cast(void)
    (printf("Hi\n"), S(2,3)).tupleof;
}

// print "Hi" twice.

-----------

This should be rewritten as (tmp=expr, TypeTuple!(tmp.field0, ...)).

(The ',' here is a comma expression.)
Comment 3 SomeDude 2012-04-23 03:26:46 UTC
With 2.059 Win32

First example gives:

PS E:\DigitalMars\dmd2\samples> rdmd bug
foo
1
2

Second example:
PS E:\DigitalMars\dmd2\samples> rdmd bug
foo

Third example:
PS E:\DigitalMars\dmd2\samples> rdmd bug
Hi
Comment 4 Kenji Hara 2012-04-23 10:40:02 UTC
This issue has been already fixed as part of bug 4940.