Casting - why no optimization by default?

4 Ansichten (letzte 30 Tage)
Daniel
Daniel am 21 Jan. 2013
function [ret] = simplespeedtest()
a = rand(1e7,1);
a = typecast(a,'uint8');
tic
ret(1) = sum(a==' '); %slowest
toc
tic
ret(2) = sum(char(a)==' '); %medium
toc
tic
ret(3) = sum(a==32); %faster
toc
tic
ret(4) = sum(a==uint8(32)); %fastest
toc
I get the following output on 2012b, Core i7:
Elapsed time is 0.247541 seconds.
Elapsed time is 0.216122 seconds.
Elapsed time is 0.139700 seconds.
Elapsed time is 0.074219 seconds.
Surely Matlab should know that all are equivalent and optimize for the fastest version - 3x better than the slowest. Do other people see this behavior, and does anyone maintain a list of things like this which are good for an easy speed boost?
  3 Kommentare
Daniel
Daniel am 21 Jan. 2013
[Two Daniels! I'm Daniel-One]: I've only just realized that chars can be wide, and of arbitrary encoding - hence the need for a char class. Is there a Matlab setting to treat chars as uint8s?
Daniel Shub
Daniel Shub am 21 Jan. 2013
That seems to be a different and unrelated question. You should ask it as a new question.

Melden Sie sich an, um zu kommentieren.

Antworten (1)

Jan
Jan am 21 Jan. 2013
Bearbeitet: Jan am 21 Jan. 2013
When variables of two different types are compared, the shorter has to be converted to the longer one. Characters have the type mxCHAR, which is an "unsigned short" or "uint16_T". So for the first comparison, the eq operator has to convert the [8e7 x 1] vector a 1 byte to a [8e7 x 1] a 2 bytes.
I have no idea why the implicite conversion in a==' ' is slower than the explicite conversion char(a)==' '. I assume, that in both cases the complete array in casted at first.
a=32 should cause a conversion of a to the type double, such that 8*8e7 bytes are required. In opposite to the actual comparison, getting the memory should be more expensive. But Matlab is optimiozed for the handling of doubles, such that perhaps the casting is done on the fly, this means element by element.
Of course a==uint8(32) is the fastest comparison, because no conversion is required.
The assumes behaviour should be visible in the performance monitor of the OS, which should show the addition need of memory.
[EDITED] You cannot cast to UINT32 by default, because this looses significant information, when data have more bits or even a floating point type. What so do you expect and want for:
single(pi) == pi
? Is the RHS converted to a single and true is replied, or the LHS to a double and you get false? Or what about:
uint8(0) == -1
Now converting the RHS to a UINT8 would definitely an error - depending on what you expect.
Therefore the eq operator must convert the data to the type with the higher precision. In case of uint64 and double it is questionable, which one has the higher precision.

Produkte

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by