Is all this Invarient **** er... stuff, premature optimisation?
p9e883002 at sneakemail.com
p9e883002 at sneakemail.com
Sun Apr 27 16:43:43 PDT 2008
Hi all,
'scuse me for not being familiar with previous or ongoing discussion on this
subject, but I'm just coming back to D after a couple of years away.
I have some strings read in from external source that I need to convert to
uppercase. A quick look at Phobos and I find std.string has a toupper method.
import std.stdio;
import std.string;
int main( char[][] args ) {
char[] a = args[ 0 ].toupper();
writefln( a );
return 0;
}
c:\dmd\test>dmd junk.d
junk.d(5): function std.string.toupper (invariant(char)[]) does not match
parameter types (char[])
junk.d(5): Error: cannot implicitly convert expression (args[0u]) of type char[]
to invariant(char)[]
junk.d(5): Error: cannot implicitly convert expression (toupper(cast(invariant
(char)[])(args[0u]))) of type invariant(char)[] to char[]
Hm. Okey dokey.
import std.stdio;
import std.string;
int main( char[][] args ) {
char[] a = ( cast(invariant(char)[]) args[ 0 ] ).toupper();
writefln( a );
return 0;
}
junk.d(5): Error: cannot implicitly convert expression (toupper(cast(invariant
(char)[])(args[0u]))) of type invariant(char)[] to char[]
Shoulda known :(
import std.stdio;
import std.string;
int main( char[][] args ) {
string a = ( cast(invariant(char)[]) args[ 0 ] ).toupper();
writefln( a );
return 0;
}
c:\dmd\test>dmd junk.d
c:\dmd\test>junk
C:\DMD\TEST\JUNK.EXE
Great! Now I need to replace the bit in the middle:
import std.stdio;
import std.string;
int main( char[][] args ) {
string a = ( cast(invariant(char)[]) args[ 0 ] ).toupper();
a[ 2 .. 4 ] = "XXX";
writefln( a );
return 0;
}
c:\dmd\test>dmd junk.d
junk.d(6): Error: slice a[cast(uint)2..cast(uint)4] is not mutable
Wha..? What's the point in having slices if I can't use them?
import std.stdio;
import std.string;
int main( char[][] args ) {
char[] a = cast(char[]) ( cast(invariant(char)[]) args[ 0 ] ).toupper();
a[ 2 .. 4 ] = "XXX";
writefln( a );
return 0;
}
Finally, it works. But can you see what's going on in line 5 amongst all that
casting? Cos I sure can't.
So, I read that all this invarient stuff is about efficiency. For whom?
Must be the compiler because it sure ain't about programmer efficiency.
Ah. Maybe I meant to ignore the beauty of slices and use strings and method
calls for everything?
import std.stdio;
import std.string;
int main( string[] args ) {
string a = args[ 0 ].toupper();
a.replace( a[ 2 .. 4 ], "XXX" );
writefln( a );
return 0;
}
Compiles clean and runs:
c:\dmd\test>dmd junk.d
c:\dmd\test>junk
C:\DMD\TEST\JUNK.EXE
But does nothing!
import std.stdio;
import std.string;
int main( string[] args ) {
string a = args[ 0 ].toupper();
a = a.replace( a[ 2 .. 4 ], "XXX" );
writefln( a );
return 0;
}
c:\dmd\test>dmd junk.d
c:\dmd\test>junk
C:XXXMD\TEST\JUNK.EXE
Finally, it runs. But at what cost? The 'immutable' a has ended up being mutated.
I still had to specify the slice, but I had to call another method call to actually
do the deed.
Of course, a wasn't really mutated. Instead, args[0] was copied and then
mutated and labelled a. Then a was copied and mutated and reassigned the
mutated copy.
So, that's two copies of the string, plus a slice, plus an extra method call to
achieve what used to be achievable in place on the original string. Which is now
immutable, but I'll never need it again.
Of course, on these short 1-off strings it doesn't matter a hoot. But when the
strings are 200 to 500 characters a pop and there are 20,000,000 of them. It
matters.
Did I suggest this was an optimisation?
Whatever immutability-purity cool aid you've been drinking, please go back to
coke. And give us usable libraries and sensible implicit conversions. Cos this sucks
bigtime.
b.
More information about the Digitalmars-d
mailing list