如何有效地计算字符串单元格数组的字符串长度

Mar*_*iet 2 string matlab

我在Matlab中有一个单元格数组:

strings = {'one', 'two', 'three'};
Run Code Online (Sandbox Code Playgroud)

如何有效地计算所有三个字符串的长度?现在我使用for循环:

lengths = zeros(3,1);
for i = 1:3
    lengths(i) = length(strings{i});
end
Run Code Online (Sandbox Code Playgroud)

但是当你有大量的字符串时,这是不可用的(我有480,863个字符串).有什么建议?

And*_*ein 9

您还可以使用:

cellfun(@length, strings)
Run Code Online (Sandbox Code Playgroud)

它不会更快,但会使代码更清晰.
关于缓慢,您应首先运行探查器以检查瓶颈在哪里.只有这样才能优化.

编辑:我刚刚回忆起'长度'曾经是旧版Matlab版本中cellfun的内置函数.所以它可能实际上更快!尝试

 cellfun('length',strings)
Run Code Online (Sandbox Code Playgroud)

编辑(2):我不得不承认我的第一个答案是疯狂猜测.在@Rodin的评论之后,我决定查看加速.

以下是基准测试的代码:

首先,生成大量字符串并保存到磁盘的代码:

function GenerateCellStrings()
    strs = cell(1,10000);
    for i=1:10000
        strs{i} = GenerateRandomString();
    end
    save strs;
end

function st = GenerateRandomString()
    MAX_STR_LENGTH = 1000;
    n = randi(MAX_STR_LENGTH);
    st = char(randi([97 122], 1,n ));

end
Run Code Online (Sandbox Code Playgroud)

那么,基准本身:

 function CheckRunTime()
    load strs;
    tic;
    disp('Loop:');
    for i=1:numel(strs)
        n = length(strs{i});
    end
    toc;

    disp('cellfun (String):');
    tic;
    cellfun('length',strs);
    toc;

    disp('cellfun (function handle):');
    tic;
    cellfun(@length,strs);
    toc;

end
Run Code Online (Sandbox Code Playgroud)

结果是:

循环:
经过的时间是0.010663秒.
cellfun(String):
经过的时间是0.000313秒.
cellfun(函数句柄):
经过的时间是0.006280秒.

哇!!'length'语法比循环快约30倍!我只能猜到它变得如此之快.也许是它length特别认可的事实.可能是JIT优化.

编辑(3) - 我发现了加速的原因.这确实是length特别的认可.感谢@reve_etrange的信息.

  • @Andrey在一个无关的问题中要求解释.当使用带有`cellfun`的预定义函数名字符串时性能提高的原因是(旧的,原始的)`cellfun`代码具有这些函数的显式代码路径.[未记载的MATLAB](http://undocumentedmatlab.com/blog/cellfun-undocumented-performance-boost/)有一篇关于[行为]的帖子(http://www.mathworks.com/help/techdoc/ref/cellfun .html)(参见"向后兼容性"). (2认同)