I'm looking for the method to generate a formatted string
the fastest.
Consider this generic case:
input = 1;
out = sprintf('fprintf(obj.Parent.Interface, \'':OUTP
%s\'');', num2str(input));
which results in:
out =
fprintf(obj.Parent.Interface, ':OUTP 1');
This is not the fastest method though. There are two
problems. The input could be either a number or a string,
and we need to make sure that it parses properly in sprintf
in either case, i.e. 1 or '1'. sprintf with the %s is not
as fast as just string contenation (at least in my tests).
As in this code for string inputs:
input = '1';
tic
for index = 1:100000
out = ['fprintf(obj.Parent.Interface, '':OUTP ', input,
''');'];
end;
toc
tic
for index = 1:100000
out = sprintf('fprintf(obj.Parent.Interface, \'':OUTP
%s\'');', input);
end;
toc
Elapsed time is 0.419424 seconds.
Elapsed time is 1.598270 seconds.
But this code only works if the input is a string, which
sometimes it may get entered as a number. Using num2str in
either of the above cases slows it considerably. The best
that I could come up with is:
tic
for index = 1:100000
input = 1;
if isnumeric(input)
input = sprintf('%0.15g',input);
end;
out = ['fprintf(obj.Parent.Interface, '':OUTP ', input,
''');'];
end;
toc
Elapsed time is 2.577910 seconds.
Does anyone see an obvious way to speed up the string
concatenation? Its good enough now, but I thought I'd see if
there was anything faster that I don't know of.
Thanks,
Jesse
The astute reader may notice the output is a fprintf string.
No, its not being executed in an eval. Yes, fprintf could
work similarly, except this is for the instrument control
toolbox, and it works differently than the normal fprintf,
i.e. it can't format strings.
fmt={
'this is the value %d'
'this is the value %s'
};
v=1;
r=sprintf(fmt{ischar(v)+1},v)
% r = this is the value 1
c='1234'
r=sprintf(fmt{ischar(c)+1},c)
% r = this is the value 1234
% note: this can easily be vectorized...
% timing (ic2.2*2.6mhz/2gb/winvista.sp1/r2008a):
% Elapsed time is 2.973561 seconds. % <- your solution
% Elapsed time is 1.196135 seconds. % <- this solution
tic
for index = 1:100000
input = 1;
if isnumeric(input)
input = sprintf('%0.15g',input);
end;
out = ['this is the value ', input];
end;
toc
fmt={
'this is the value %d'
'this is the value %s'
};
tic
for i=1:100000
v=1;
r=sprintf(fmt{ischar(v)+1},v);
end
toc
us wrote:
> "Jesse Lai":
> <SNIP dynamic string creation...
>
> one of the many solutions
>
> fmt={
> 'this is the value %d'
> 'this is the value %s'
> };
> v=1;
> r=sprintf(fmt{ischar(v)+1},v)
> % r = this is the value 1
> c='1234'
> r=sprintf(fmt{ischar(c)+1},c)
> % r = this is the value 1234
> % note: this can easily be vectorized...
>
> % timing (ic2.2*2.6mhz/2gb/winvista.sp1/r2008a):
>
> % Elapsed time is 2.973561 seconds. % <- your solution
> % Elapsed time is 1.196135 seconds. % <- this solution
>
> tic
> for index = 1:100000
> input = 1;
> if isnumeric(input)
> input = sprintf('%0.15g',input);
> end;
> out = ['this is the value ', input];
> end;
> toc
> fmt={
> 'this is the value %d'
> 'this is the value %s'
> };
> tic
> for i=1:100000
> v=1;
> r=sprintf(fmt{ischar(v)+1},v);
> end
> toc
>
us,
Elegant, thank you. I will try timing in a sec, but the generation of
the cell fmt would need to be done inside the function in my code, so it
would need to be included in the loop timing. There isn't a clean way
to put it outside I don't think, but will think on it a bit. I'll check
to make sure its still faster even with the cell creation, I know
sometimes that can be slow.
I've run a few additional timing experiments using us's and
my original code. Us's solution is nice, but slow(er) for
the %s case. I propose testing both the numeric and string
input cases to determine speed.
clear
tic
for index = 1:100000
ip1 = 1;
if isnumeric(ip1)
ip1 = sprintf('%d',ip1);
end;
out1 = ['this is the value ', ip1];
end;
time1 = toc;
tic
for index = 1:100000
ip2 = '1';
if isnumeric(ip2)
ip2 = sprintf('%d',ip2);
end;
out2 = ['this is the value ', ip2];
end;
time2 = toc;
disp(sprintf('Numeric: %f sec\nString: %f sec\nTotal: %f\n',
time1, time2, time1+time2));
clear
fmt={
'this is the value %d'
'this is the value %s'
};
tic
for index = 1:100000
ip1 = 1;
r1=sprintf(fmt{ischar(ip1)+1},ip1);
end;
time1=toc;
tic
for index = 1:100000
ip2 = '1';
r2=sprintf(fmt{ischar(ip2)+1},ip2);
end;
time2 = toc;
The modified code takes a slightly different approach, but
has the drawback the format is kept in two locations. The
code will be autogenerated in my application, so not a big
deal, but not as elegant as us's solution. Anyone have any
other ideas for speed improvement?
Public Submission Policy
NOTICE: Any content you submit to MATLAB Central, including personal information, is not subject to the protections which may be afforded information collected under other sections of The MathWorks, Inc. Web site. You are entirely responsible for
all content that you upload, post, e-mail, transmit or otherwise make available via MATLAB Central. The MathWorks does not control the content posted by visitors to MATLAB Central and, does not guarantee the accuracy, integrity, or quality of such content.
Under no circumstances will The MathWorks be liable in any way for any content not authored by The MathWorks, or any loss or damage of any kind incurred as a result of the use of any content posted, e-mailed, transmitted or otherwise made available
via MATLAB Central. Read the complete Disclaimer prior to use.