我有一个名为 skj
的数组。 skj
包含 200 万行数字 (2000000x1
uint32
)。
我想要计算以下内容:
string_skj = num2str(skj);
当我运行以上代码时,需要大约1分钟的时间,有没有更快的方法?
我有一个名为 skj
的数组。 skj
包含 200 万行数字 (2000000x1
uint32
)。
我想要计算以下内容:
string_skj = num2str(skj);
当我运行以上代码时,需要大约1分钟的时间,有没有更快的方法?
num2str
(或int2str
)更有效地处理列向量的方法,我已经想出了两种解决方案。
编辑: 在所有这些工作之后,@Luis Mendo进来把它全部推翻了 :'(
编辑: 现在@Daniel又改进了所有先前的选项!
给定我们的行向量V
,如下:
V = uint32(randi(100, 200000, 1));
A = num2str(V);
使用 *
B = char(strsplit(num2str(V.')).');
或者不使用 num2str
的错误检查
C = char(strsplit(sprintf('%d\n', V)).');
C = C(1:end-1, :); % Remove extraneous '\n'
B
和C
与A
略有不同。 num2str
在前面填充一个空格' '
,而B
和C
在后面填充一个空格。
在下面的例子中,D
和E
都使用了前导的0
进行填充,因此无法与A
、B
或C
完全匹配。
-----num2str() on row vector [Original]-----
Elapsed time is 3.501976 seconds.
Name Size Bytes Class Attributes
A 200000x3 1200000 char
-----num2str() on column vector [IKavanagh modified from Hennadii Madan]-----
Elapsed time is 0.660878 seconds.
Name Size Bytes Class Attributes
B 200000x3 1200000 char
-----sprintf() on row vector [IKavanagh]-----
Elapsed time is 0.582472 seconds.
Name Size Bytes Class Attributes
C 200000x3 1200000 char
-----dec2base() on row vector [Luis Mendo]-----
Elapsed time is 0.042563 seconds.
Name Size Bytes Class Attributes
D 200000x3 1200000 char
-----myfastint2str() on row vector [Daniel]-----
Elapsed time is 0.011894 seconds.
Name Size Bytes Class Attributes
E 200000x3 1200000 char
clear all
close all
clc
V = uint32(randi(100, 200000, 1));
for k = 1:50000
tic(); elapsed = toc(); % Warm up tic/toc
end
disp('-----num2str() on row vector [Original]-----');
tic;
A = num2str(V);
toc, whos A
disp('-----num2str() on column vector [IKavanagh modified from Hennadii Madan]-----');
tic;
B = char(strsplit(num2str(V.')).');
toc, whos B
disp('-----sprintf() on row vector [IKavanagh]-----');
tic;
C = char(strsplit(sprintf('%d\n', V)).');
C = C(1:end-1, :); % Remove extraneous '\n'
toc, whos C
disp('-----dec2base() on row vector [Luis Mendo]-----');
tic;
D = dec2base(V, 10);
toc, whos D
disp('-----myfastint2str() on row vector [Daniel]-----');
tic;
E = myfastint2str(V);
toc, whos E
sprintf
的向量化版本的工作方式。基本上,对于这个例子,它将行向量和列向量视为相同。 - IKavanaghy = dec2base(skj,10);
以下是一个快速测试:
>> skj = uint32(2^32*rand(1e6,1)); %// random data
>> tic, y = num2str(skj); toc
Elapsed time is 22.823348 seconds.
>> tic, z = dec2base(skj,10); toc
Elapsed time is 1.235942 seconds.
dec2base
会产生前导零而不是前导空格。>> y(1:5,:)
ans =
3864067979
1572155259
1067755677
2492696731
561648530
>> z(1:5,:)
ans =
3864067979
1572155259
1067755677
2492696731
0561648530
如果您自己实现 int2str 函数,那么您可以远远超越原始函数的性能。
function [ o ] = myfastint2str( x )
maxvalue=max(x(:));
%maxvalue=intmax(class(x));%Alternative implementation based on class
required_digits=ceil(log(double(maxvalue+1))/log(10));
o=repmat(x(1)*0,size(x,1),required_digits);%initialize array of required size
for c=size(o,2):-1:1
o(:,c)=mod(x,10);
x=(x-o(:,c))/10;
end
o=char(o+'0');
end
警告:输出结果可能是可行的,但是不正确。
编辑:一个超级快速的“解决方案”输出不是一列,而是一个带有换行符作为分隔符的字符串。如果您尝试打印它,它看起来会相同。
>> tic;a = sprintf('%d\n',skj);toc
Elapsed time is 0.422143 seconds
编辑: 旧的“解决方案”
尝试在之前和之后进行转置。例如num2str(skj.').'
>> skj = ones(2000000,1,'uint32');
>> tic;num2str(skj);toc
Elapsed time is 23.305860 seconds.
>> tic;num2str(skj.');toc
Elapsed time is 1.044551 seconds.
num2str(skj.')
比 num2str(skj)
更快呢? - Davidnum2str(skj.').'
会产生错误的输出,因为转置对字符数组的影响。你应该将它改为num2str(skj.')
。 - IKavanaghskj = uint32(1:200000)'
。它要么创建一个包含所有元素的单个字符串,要么在转置时将每个字符放在单独的一行上,我相信这不是任何人想要的。 - zelanix
a = sprintf('%d\n',skj)
。 - Hennadii Madan