【问题标题】:matlab: speed up for loop with string analysismatlab:通过字符串分析加速for循环
【发布时间】:2017-04-25 13:32:20
【问题描述】:

我有一个包含三列的非常简单的 csv 文件。现在我想尽快将这些列加载到 matlab 矩阵中。

目前我做的是这个

    fid = fopen(inputfile, 'rt');
    g = textscan(fid,'%s','delimiter','\r\n');
    tdata = g{1};
    fclose(fid);
    
    results = zeros([numel(tdata)-4], 3);
    tic
    display('start reading data...');
    for r = 4:numel(tdata)
        if ~mod(r, 100) 
            display(['data row: ' num2str(r) ' / ' num2str(numel(tdata))]);
        end
        entries = strsplit(tdata{r}, ',');
        results(r-3,1) = str2double(strrep(entries{1},',', '.'));
        results(r-3,2) = str2double(strrep(entries{2},',', '.'));
        results(r-3,3) = str2double(strrep(entries{3},',', '.'));
    end

然而,对于 200 000 行,这需要大约 30 秒。这意味着每行 150 µs。这真的很慢。 parfor 不接受该代码。

现在我想知道是什么导致了 for 循环中的瓶颈以及如何加快它的速度。

这里测量的时间:

str2double 578253 调用 29.631s

strsplit 192750 调用 13.388s

编辑: 内容在文件中有这样的结构

  0.000000,  -0.00271,   5394147
  0.000667,  -0.00271,   5394148
  0.001333,  -0.00271,   5394149
  0.002000,  -0.00271,   5394150

【问题讨论】:

  • 你看过code profiling吗?您还可以使用 GUI 中的“运行和时间”选项来确定慢步。
  • 我将结果添加到帖子中

标签: matlab performance for-loop


【解决方案1】:

我认为通过不同的方式调用 textscan 可以改进很多。

你这样做:

g = textscan(fid,'%s','delimiter','\r\n');

然后调用 tdata = g{1};

如果 textscan 被正确调用,它应该已经拆分了所有数据,并将其作为数字返回。

试试这个:

g=textscan(fid,'%f,%f,%f,'delimiter','\r\n')

它应该返回三个单元格数组,列中包含您的值。要转换为矩阵,您可以使用:

g=cell2mat(g)

我在 0.12 秒内导入了 20 万行。

您的代码似乎还有其他一些解决方法。您从 r=4 开始,您似乎有 3 行不想阅读。所以在 fopen 之后你可以调用 3 次

[~] =fgetl(fid) 

进入文件中有趣的部分。

您还首先使用 ',' 作为分隔符来分割行。但是将所有的 ',' 替换为 '.'。这不会做任何事情,所有的“,”都已经消失了,因为它们被用作分隔符。

【讨论】:

  • 那行不通。 g=textscan(fid,'%f,%f,%f\r\n') 只返回一行。
  • 它适用于g=textscan(fid,'%f,%f,%f','delimiter','\r\n'); dataOutput=cell2mat(g); 现在结果时间是 0.5 秒。加速60倍。
  • 这是一个相当大的进步!我更正了答案。
【解决方案2】:

如果您使用csvread,则不需要使用str2doublestrsplit,您说这是慢行...对于csv 可能要快得多。

您可以将以上所有代码替换为:

results = csvread(inputfile);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-26
    相关资源
    最近更新 更多