Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance Matlab函数性能-循环太多_Performance_Matlab_Function_Vectorization - Fatal编程技术网

Performance Matlab函数性能-循环太多

Performance Matlab函数性能-循环太多,performance,matlab,function,vectorization,Performance,Matlab,Function,Vectorization,我必须在一个txt文件中写入许多行中的若干信息。结果是一个类似以下内容的文件: result.txt: RED;12;7;0;2;1;4;7;0.0140 RED;12;7;0;2;2;9;7;0.1484 RED;12;7;0;2;3;7;4;0.1787 RED;12;7;0;2;4;2;6;0.7891 RED;12;7;0;2;5;9;6;0.1160 RED;12;7;0;2;6;9;1;0.9893 ... 这是由以下代码构建的(具有一些缩减的维度): 我在(stackoverfl


我必须在一个txt文件中写入许多行中的若干信息。结果是一个类似以下内容的文件:

result.txt:
RED;12;7;0;2;1;4;7;0.0140
RED;12;7;0;2;2;9;7;0.1484
RED;12;7;0;2;3;7;4;0.1787
RED;12;7;0;2;4;2;6;0.7891
RED;12;7;0;2;5;9;6;0.1160
RED;12;7;0;2;6;9;1;0.9893
...
这是由以下代码构建的(具有一些缩减的维度):


我在(stackoverflow post)中看到了一些矢量化,但我认为不可能在这里应用。有什么想法吗
提前感谢

实际上,似乎只是先创建所有内容,然后再编写(我尝试的方式)并不能提高速度。我最初的想法是用
save(file,data,'-ascii')
保存数据,但结果出乎意料

如果您只需要数字数据,那么您可能可以使用
dlmwrite
,但我想这现在不是一个选项

以下是我尝试与您的原始代码进行比较的时间,包括一些假设输入:

str1 = 'RED';
num1 = 4;
day = rand(10);
vect1 = 1:7;
vect2 = 1:180;
MD = rand(7,180,10,15);
y=[];

tic
for i1 = 1:15   
    for i2 = 1:10    
        for i3 = 1:7           
           for i4= 1:180

                x=sprintf('%s%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%.4f \n',...
                str1,';',num1,';',i1,';',0,';',2,';',...
                day(i2,1),';',vect1(i3),';',...
                vect2(i4),';',MD(i3,i4,i2,i1));
                y{end+1} = x;
            end
        end
    end
end

fid = fopen('test.txt','w');
for i=1:length(y)
         fprintf(fid,y{i});
end
fclose(fid)
t1=toc;

tic
fid = fopen('test.txt', 'Wt');    
for i1 = 1:15   
    for i2 = 1:10    
        for i3 = 1:7           
           for i4= 1:180
                fprintf(fid,'%s%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%.4f \n',...
                str1,';',num1,';',i1,';',0,';',2,';',...
                day(i2,1),';',vect1(i3),';',...
                vect2(i4),';',MD(i3,i4,i2,i1));
            end
        end
    end
end
t2=toc;

myTime = t1 % 56 secs
originalTime = t2 % 12 secs

实际上,似乎只是先创建所有内容,然后再编写(我尝试的方式)并不能提高速度。我最初的想法是用
save(file,data,'-ascii')
保存数据,但结果出乎意料

如果您只需要数字数据,那么您可能可以使用
dlmwrite
,但我想这现在不是一个选项

以下是我尝试与您的原始代码进行比较的时间,包括一些假设输入:

str1 = 'RED';
num1 = 4;
day = rand(10);
vect1 = 1:7;
vect2 = 1:180;
MD = rand(7,180,10,15);
y=[];

tic
for i1 = 1:15   
    for i2 = 1:10    
        for i3 = 1:7           
           for i4= 1:180

                x=sprintf('%s%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%.4f \n',...
                str1,';',num1,';',i1,';',0,';',2,';',...
                day(i2,1),';',vect1(i3),';',...
                vect2(i4),';',MD(i3,i4,i2,i1));
                y{end+1} = x;
            end
        end
    end
end

fid = fopen('test.txt','w');
for i=1:length(y)
         fprintf(fid,y{i});
end
fclose(fid)
t1=toc;

tic
fid = fopen('test.txt', 'Wt');    
for i1 = 1:15   
    for i2 = 1:10    
        for i3 = 1:7           
           for i4= 1:180
                fprintf(fid,'%s%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%.4f \n',...
                str1,';',num1,';',i1,';',0,';',2,';',...
                day(i2,1),';',vect1(i3),';',...
                vect2(i4),';',MD(i3,i4,i2,i1));
            end
        end
    end
end
t2=toc;

myTime = t1 % 56 secs
originalTime = t2 % 12 secs

优化代码可以做的一件事是寻找“重复”的代码位。在您的例子中,您可以在最里面的循环中格式化所有的结果字符串——尽管大部分字符串没有改变。您还可以“格式化”分隔符字符串
;”多次-您可以将其直接放在格式化字符串中(您可以在格式化字符串中插入文本和格式化命令)。我以几种不同的方式组合了这些想法,并对它们进行了计时:

str1='hello';
num1=123;
天=(1:10)';
vect1=(1:7)';
vect2=(1:180)';
MD=兰特(7180,10,15);
路径_结果='./mixedOutput1.txt';
fid=fopen(路径结果“Wt”);
抽搐
对于i1=1:15
对于i2=1:10
对于i3=1:7
对于i4=1:180
%/*打印所有值*/
fprintf(fid),%s%s%d%s%d%s%d%s%d%d%s%d%s%d%s%d%s%.4f\n',。。。
str1,,;,num1,,,i1,;,0,;,2,。。。
日(i2,1),“;”,向量1(i3),“;”,。。。
vect2(i4),“;”,MD(i3,i4,i2,i1));
结束
结束
结束
结束
fprintf(1,'原始循环时间:%.2f秒\n',toc)
fclose(fid);
%%
路径_结果='./mixedOutput2.txt';
fid=fopen(路径结果“Wt”);
抽搐
对于i1=1:15
对于i2=1:10
对于i3=1:7
对于i4=1:180
%/*打印所有值*/
fprintf(fid,'%s;%d;%d;0;2;%d;%d;%d;%4f\n',。。。
str1,num1,i1,天(i2,1),vect1(i3),vect2(i4),MD(i3,i4,i2,i1);
结束
结束
结束
结束
fprintf(1,'更快循环的时间:%.2f秒\n',toc)
fclose(fid);
%%
路径_结果='./mixedOutput3.txt';
fid=fopen(路径结果“Wt”);
抽搐
y=单元(1,15*10*7*180);
cc=0;
对于i1=1:15
对于i2=1:10
对于i3=1:7
对于i4=1:180
%/*打印所有值*/
cc=cc+1;
y{1,cc}=sprintf(“%s;%d;%d;0;2;%d;%d;%d;%d;%4f\n',。。。
str1,num1,i1,天(i2,1),vect1(i3),vect2(i4),MD(i3,i4,i2,i1);
结束
结束
结束
结束
fprintf(1,'带sprintf中间步骤的循环时间:%.2f秒\n',toc)
fprintf(fid,'%s',y{:});
fprintf(1,'包括文件写入的时间:%.2f秒\n',toc);
fclose(fid);
%%优化循环更多:
路径_结果='./mixedOutput4.txt';
fid=fopen(路径结果“Wt”);
抽搐
y=单元(1,15*10*7*180);
cc=0;
对于i1=1:15
对于i2=1:10
对于i3=1:7
x=sprintf(“%s;%d;%d;0;2;%d;%d;”。。。
str1,num1,i1,天(i2,1),vect1(i3));
对于i4=1:180
fprintf(fid,'%s%d;%.4f\n'。。。
x、 vect2(i4),MD(i3,i4,i2,i1);
结束
结束
结束
结束
fprintf(1,'最快循环的时间:%.2f秒\n',toc);
fclose(fid);
在我的机器上,这产生了以下基准:

原始循环:15.9秒 更快的格式:9.2秒 使用sprintf时:8.2秒 预成型时间:6.2秒
“preformat”并没有尽可能有效地完成——它只是为了举例说明。中间字符串
x
的计算频率要低得多,然后重新使用

最后-我创建了一个“矢量化”版本的代码-这意味着整个
sprintf
发生在一行中。这需要使用正确的元素创建一个大单元数组(
Kahuna
,如下)——结果表明,这实际上比上面最后一个代码(使用“预格式化”)的效率略低,但这里只是以防万一:

%%真正矢量化:
抽搐
Kahuna=单元(7,15*10*7*180);
N=15*10*7*180;
N1=一(1,N);
%最终订单需要是[180 7 10 15]-首先是内环
Kahuna(1,:)=cellstr(repmat(str1,[n1]));
Kahuna(2,:)=mat2cell(repmat(num1,[N1]),N1,1);
Kahuna(3,:)=mat2cell(重塑(repmat)(重塑(1:15,1,1,1,15),[1807101]),[],1),N1,1);
Kahuna(4,:)=mat2cell(重塑)(repmat(重塑(第1天,第1天,第1天,第10天,第1天),[1807115]),[],第1天),第1天,第1天);
Kahuna(5,:)=mat2cell(重塑(repmat)(重塑(vect1,1,7,1,1),[180 110]),[],1),N1,1);
Kahuna(6,:)=mat2cell(重塑(repmat)(重塑(vect2,180,1,1,1),[1 7 10 15]),[],1),N1,1);
Kahuna(7,:)=mat2cell(重塑(排列[2 1 3 4]),[],1),N1,1);
x=sprintf(“%s;%d;%d;0;2;%d;%d;%d;%4f\n',Kahuna{:});
toc

优化代码的方法之一是寻找“重复”的代码位。在您的例子中,您可以在最里面的循环中格式化所有的结果字符串——尽管大部分字符串没有改变。您还可以“格式化”分隔符字符串
;”多次-您可以直接在格式化字符串中使用它
fmt       = sprintf('%s;%d;%%d;%d;%d;%%d;%%d;%%d;%%.4f \\n',str1,num1,0,2)
fmt =
RED;4;%d;0;2;%d;%d;%d;%.4f \n
x = sprintf(fmt, i1, day(i2,1), vect1(i3), vect2(i4), MD(i3,i4,i2,i1));
tic
[a,b,c,d] = ndgrid(vect2,vect1,day,1:15);
out       = sprintf(fmt, [d(:), c(:), b(:), a(:), reshape(permute(MD,[2,1,3,4]),[],1)]'); 
toc