gpt4 book ai didi

matlab - 在 MATLAB 中经常附加文本的最佳方法

转载 作者:太空宇宙 更新时间:2023-11-03 19:55:48 24 4
gpt4 key购买 nike

我正在编写一个 matlab 脚本,最终将数百行文本输出到一个文件中。现在我只是继续附加文本,如:

Output = [];
Output = [Output NewText];

但我认为这是低效的,因为它每次都必须创建一个新矩阵。有什么更好的方法。

在我准备好编写所有文本之前我无法打开文件,所以我不能继续在输出文件上使用 fprintf。

最佳答案

对此没有明显的最佳答案,至少对我而言是这样。一些选项是:

  1. 正是你在做什么,为每次迭代递增地附加到一个字符串
  2. 智能地增加累积字符串以减少重新分配的次数(@macduff 答案的核心)
  3. 使用字符串元胞数组,并智能地重新分配它。 (我很确定)这只会强制重新分配指针,而不是完全重新分配字符串内容。
  4. 使用一些 Java 魔法来处理字符串累积。 Java 库有许多有用的特性(例如 StringBuilder 类),但 Matlab-Java 接口(interface)速度很慢。
  5. 增量地直接写入文件(我知道您已将此从问题的考虑中删除,但它仍然是一个有用的基线。)

我的直觉表明性能顺序是:

  • 最佳:(2 或 3)
  • 中:(4 或 5)
  • 最差:(1)

但并不明显。

幸运的是它很容易测试。下面的大测试 block 中包含所有 5 个选项(加上一些测试包装器)的实现。在我的计算机上(一台带有 SSD 的相当不错的计算机,结果可能会有所不同)上的结果如下(为格式化而添加到代码输出的空格):

-------------Start of file write speed tests.  (nLines = 1)------------
Time for BaseLine operation: 0.001540 sec
Time for AutoAllocate operation: 0.001264 sec
Time for AutoAllocateCell operation: 0.003492 sec
Time for JavaStringBuilder operation: 0.001395 sec
Time for IncrementalWriteToFile operation: 0.001057 sec
-------------Start of file write speed tests. (nLines = 100)------------
Time for BaseLine operation: 0.011909 sec
Time for AutoAllocate operation: 0.014067 sec
Time for AutoAllocateCell operation: 0.011517 sec
Time for JavaStringBuilder operation: 0.021291 sec
Time for IncrementalWriteToFile operation: 0.016213 sec
-------------Start of file write speed tests. (nLines = 10000)------------
Time for BaseLine operation: 3.778957 sec
Time for AutoAllocate operation: 1.048480 sec
Time for AutoAllocateCell operation: 0.856269 sec
Time for JavaStringBuilder operation: 1.657038 sec
Time for IncrementalWriteToFile operation: 1.254080 sec
-------------Start of file write speed tests. (nLines = 100000)------------
Time for BaseLine operation: 358.312820 sec
Time for AutoAllocate operation: 10.349529 sec
Time for AutoAllocateCell operation: 8.539117 sec
Time for JavaStringBuilder operation: 16.520797 sec
Time for IncrementalWriteToFile operation: 12.259307 sec

因此,如果您使用的是“100 条”线,这可能无关紧要;做任何工作。如果您知道性能很重要,那么我会使用“AutoAllocateCell”选项。这是非常简单的代码(见下文)。如果您没有足够的内存来一次将整个文件存储在内存中,我会使用“AutoAllocateCell”选项并定期刷新到文件。


测试代码:

%Setup
cd(tempdir);
createLineLine = @(n, s) sprintf('[%04d] %s\n', n, s);
createRandomLine = @(n) createLineLine(n, char(randi([65 122],[1, round(rand*100)])));

for nLines = [1 100 10000 100000]
fprintf(1, ['-------------Start of file write speed tests. (nLines = ' num2str(nLines) ')------------\n']);

%% Baseline -----------------------------
strName = 'BaseLine';
rng(28375213)
tic;

str = [];
for ix = 1:nLines;
str = [str createRandomLine(ix)];
end

fid = fopen(['WriteTest_' strName],'w');
fprintf(fid, '%s', str);
fclose(fid);

fprintf(1, 'Time for %s operation: %f sec\n', strName, toc);

%% AutoAllocated string -----------------------------
strName = 'AutoAllocate';
rng(28375213)
tic;

str = blanks(256);
ixLastValid = 0;
for ix = 1:nLines;
strNewLine = createRandomLine(ix);
while (ixLastValid+length(strNewLine)) > length(str)
str(end*2) = ' '; %Doubles length of string
end
str(ixLastValid + (1:length(strNewLine))) = strNewLine;
ixLastValid = ixLastValid+length(strNewLine);
end

fid = fopen(['WriteTest_' strName],'w');
fprintf(fid, '%s', str(1:ixLastValid));
fclose(fid);

fprintf(1, 'Time for %s operation: %f sec\n', strName, toc);

%% AutoAllocated cell array -----------------------------
strName = 'AutoAllocateCell';
rng(28375213)
tic;

strs = cell(256,1);
ixLastValid = 0;
for ix = 1:nLines;
if ix>length(strs);
strs{end*2} = {}; %Doubles cell array size;
end
strs{ix} = createRandomLine(ix);
ixLastValid = ixLastValid + 1;
end

fid = fopen(['WriteTest_' strName],'w');
fprintf(fid, '%s', strs{1:ixLastValid});
fclose(fid);

fprintf(1, 'Time for %s operation: %f sec\n', strName, toc);

%% Java string builder -----------------------------
strName = 'JavaStringBuilder';
rng(28375213)
tic;

sBuilder = java.lang.StringBuilder;
for ix = 1:nLines;
sBuilder.append(createRandomLine(ix));
end

fid = fopen(['WriteTest_' strName],'w');
fprintf(fid, '%s', char(sBuilder.toString()));
fclose(fid);

fprintf(1, 'Time for %s operation: %f sec\n', strName, toc);

%% Incremental write to file -----------------------------
strName = 'IncrementalWriteToFile';
rng(28375213)
tic;

fid = fopen(['WriteTest_' strName],'w');
for ix = 1:nLines;
fprintf(fid, '%s', createRandomLine(ix));
end
fclose(fid);

fprintf(1, 'Time for %s operation: %f sec\n', strName, toc);
end

关于matlab - 在 MATLAB 中经常附加文本的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17372291/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com