Сравнение строк в массиве ячеек строк с Matlab Coder - PullRequest
0 голосов
/ 10 февраля 2019

Я пытаюсь использовать панель инструментов 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 - строка.Код в основном сравнивает каждый элемент от list до compare и возвращает 1, если они совпадают, и 0 в противном случае.(Я делаю это, чтобы ускорить выполнение, потому что N может быть довольно большим - от 10 до 20 миллионов элементов.)

Когда я запускаю codegen list_iterator в Командном окне, я получаю следующую ошибку:

Тип входного аргумента 'сравнение' для функции 'list_iterator' не указан.Используйте операторы -args или preconditioning для указания типов ввода.

Дополнительная информация

Ошибка в ==> list_iterator Строка: 1 Столбец: 18

Ошибка генерации кода: просмотр отчета об ошибках

Ошибка при использовании codegen

Я знаю, что должен указывать типы входов при использовании codegen, но я не уверен, как это сделать для ячейкимассив строк, элементы которого могут быть разной длины.Строка compare также может иметь различную длину в зависимости от вызова функции.

1 Ответ

0 голосов
/ 10 февраля 2019

Вы можете использовать функцию 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, оно предоставляет графические средства для определения этих сложных входных данных.,Оттуда вы можете экспортировать это в скрипт сборки, чтобы увидеть соответствующие 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 с массивом cell и char, который делает код еще быстрее:

function [idx] = list_iterator(compare, list)

idx = strcmp(compare, list);

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

ans =

   2.1695e-05
...