Performance penalty for using ranges
bearophile
bearophileHUGS at lycos.com
Sun Aug 25 13:22:36 PDT 2013
Paul Jurczak:
>> int test(alias F)(in int nLoops) /*pure nothrow*/ {
>> int[10] a;
>> typeof(return) n = 0;
>>
>> foreach (immutable _; 0 .. nLoops) {
>> a[4] = !a[4];
>> n += F(a);
>> }
>>
>> return n;
>> }
>
> What is the purpose of "immutable _;" above? Why not "i;"?
I have used _ as variable iteration name to remind the person
that is reading the code that loop variable name is not used
inside the loop itself. When you have more of those variables you
can number them as _1, _2, or use no more than two underscores __.
And there the usage of immutable is to disallow the mutation the
iteration variable inside the loop. In my opinion, to keep code
clean and less bug-prone D should on make foreach indexes
immutable on default. This saves you from bugs when you iterate
on struct items:
struct Foo { int x; }
auto foos = [Foo(10), Foo(20)];
foreach (f; foos)
f.x++;
It's not uncommon in those cases to forget a "ref" and think foos
are changed. If iteration items are immutable as in C# this saves
you from this class of bugs.
I have asked this in past, but D lacks a "mutable" keyword for
the situations when you want to actually mutate the foreach
variable, and generally Walter didn't sound very interested on
this.
So as workaround for this language design problem, it's a good
habit to always put a const/immutable on foreach variables,
unless you don't wait it, and unless something forces you to not
use a const.
>> void main() {
>> enum size_t nLoops = 60_000_000;
>> StopWatch sw;
>>
>> foreach (alg; TypeTuple!(isPalindrome0, isPalindrome1,
>> isPalindrome2, isPalindrome3,
>> isPalindrome4)) {
>> sw.reset;
>> sw.start;
>> immutable n = test!alg(nLoops);
>> sw.stop;
>> writeln(n, " ", sw.peek.msecs);
>> }
>> }
>
> Same question here: why immutable?
It's explained here:
http://blog.knatten.org/2011/11/11/disempower-every-variable/
In short all your variables/function arguments should be tagged
as const/immutable unless the semantics of your algorithm needs
them to mutate, or unless some limit in D/Phobos forbids you to
(like when you have created a lazy range, currently you can't
assign it to const and then use it).
Bye,
bearophile
More information about the Digitalmars-d
mailing list