首页 > 解决方案 > 使用 Matlab Coder 对字符串元胞数组进行字符串比较

问题描述

我正在尝试使用 MATLAB Coder 工具箱将以下代码转换为 C:

function [idx] = list_iterator(compare, list)

idx = nan(length(list));
for j = 1:length(list)
    idx(j) = strcmp(compare, list{j});
end

list是一个 N x 1 的字符串元胞数组并且compare是一个字符串。代码基本上比较 to 的每个元素,list如果两者相同则compare返回,否则返回。(我这样做是为了加快执行速度,因为 N 可能非常大——大约 10 到 2000 万个元素。)10

当我codegen list_iterator在命令行窗口中运行时,我收到以下错误:

未指定函数“list_iterator”的输入参数“比较”的类型。使用 -args 或预处理语句来指定输入类型。

更多信息

==> list_iterator 中的错误行:1 列:18

代码生成失败:查看错误报告

使用代码生成错误

我知道我应该在使用时指定输入的类型codegen,但我不确定如何为字符串单元数组执行此操作,其元素可以具有不同的长度。根据函数调用,字符串compare也可以有不同的长度。

标签: matlabcode-generationstring-comparisonmatlab-coder

解决方案


您可以使用该函数coder.typeof来指定可变大小的输入codegen。根据我对您的示例的理解,例如:

>> compare = coder.typeof('a',[1,Inf])

compare = 

coder.PrimitiveType
   1×:inf char
>> list = coder.typeof({compare}, [Inf,1])

list = 

coder.CellType
   :inf×1 homogeneous cell 
      base: 1×:inf char
>> codegen list_iterator.m -args {compare, list}

似乎合适。

如果您查看 MATLAB Coder App,它提供了指定这些复杂输入的图形方法。从那里您可以将其导出到构建脚本以查看相应的命令行 API:

https://www.mathworks.com/help/coder/ug/generate-a-matlab-script-to-build-a-project.html?searchHighlight=build%20script&s_tid=doc_srchtitle

请注意,当我使用 尝试此示例时codegen,生成的 MEX 并不比 MATLAB 快。发生这种情况的一个原因是函数的主体相当简单,但是大量数据从 MATLAB 传输到生成的代码并返回。因此,这种数据传输开销会支配执行时间。将更多代码移至生成的 MEX 可能会改善这一点。

考虑与性能无关的codegen,你应该使用idx = false(length(list),1);而不是idx = nan(length(list));?前者是一个 Nx1 逻辑向量,而后者是一个 NxN 双矩阵,我们只在 中写入第一列list_iterator

使用您的原始代码和输入,compare = 'abcd'; list = repmat({'abcd';'a';'b'},1000,1);这给出了时间:

>> timeit(@()list_iterator(compareIn, listIn))

ans =

    0.0257

修改代码以返回向量会缩小:

function [idx] = list_iterator(compare, list)

idx = false(length(list),1);
for j = 1:length(list)
    idx(j) = strcmp(compare, list{j});
end

>> timeit(@()list_iterator(compareIn, listIn))

ans =

    0.0014

您还可以strcmp使用单元格和字符数组调用,这使代码更快:

function [idx] = list_iterator(compare, list)

idx = strcmp(compare, list);

>> timeit(@()list_iterator(compareIn, listIn))

ans =

   2.1695e-05

推荐阅读