gpt4 book ai didi

performance - 将参数传递给 cellfun matlab

转载 作者:行者123 更新时间:2023-12-04 02:38:47 34 4
gpt4 key购买 nike

您好,我有一个 char 元胞数组(由下划线分隔),我想将其转换为 double 。我在 for 循环中执行此操作,但由于维度非常大,因此需要花费大量时间。我想使用cellfun,但我不知道如何传递分隔符。

你能帮帮我吗?

listofwords = {'02_04_04_52';'02_24_34_02'};
for i = 1 : size(listofwords,1)
listofwords_double(i,:) = str2double(strsplit(listofwords{i},'_'))./1000;
end

listofwords_double2= cellfun(@strsplit , listofwords);

基准

应迪瓦卡的要求

>> benchmark1
Speedup with EVAL over NO-LOOP-SSCANF = -46.3398%
>> benchmark1
Speedup with EVAL over NO-LOOP-SSCANF = -46.4068%
>> benchmark1
Speedup with EVAL over NO-LOOP-SSCANF = -47.1129%
>> benchmark1
Speedup with EVAL over NO-LOOP-SSCANF = -46.2882%
>> benchmark1
Speedup with EVAL over NO-LOOP-SSCANF = -46.2325%
>> benchmark1
Speedup with EVAL over NO-LOOP-SSCANF = -46.0161%
>> benchmark1
Speedup with EVAL over NO-LOOP-SSCANF = -46.9728%
>> benchmark1
Speedup with EVAL over NO-LOOP-SSCANF = -46.4267%
>> benchmark1
Speedup with EVAL over NO-LOOP-SSCANF = -46.2867%
>> benchmark1
Speedup with EVAL over NO-LOOP-SSCANF = -46.3031%

最佳答案

你可以像这样使用匿名函数-

listofwords_double2= cellfun(@(x) strsplit(x,'_') , listofwords,'uni',0)

另一种使用 regexp 和单行代码的方法 -

cell2mat(cellfun(@(x) str2double(regexp(x,'_','Split'))./1000 , listofwords,'uni',0))

以性能为导向的解决方案

方法 #1

N = 4; %// Edit this to 10 in your actual case
cat_cell = strcat(listofwords,'_');
one_str = [cat_cell{:}];
one_str(end)=[];
sep_cells = regexp(one_str,'_','Split');
out = reshape(str2double(sep_cells),N,[]).'./1000; %//'# desired output

方法 #2

对上述解决方案进行基准测试表明 strcat 可能被证明是瓶颈。要摆脱它,您可以对该部分使用基于 cumsum 的方法。接下来列出 -

N = 4; %// Edit this to 10 in your actual case

lens = cellfun(@numel,listofwords);
tlens = sum(lens);
idx = zeros(1,tlens); %// Edit this to "idx(1,tlens)=0;" for more performance
idx(cumsum(lens(1:end-1))+1)=1;
idx2 = (1:tlens) + cumsum(idx);

one_str(1:max(idx2))='_';
one_str(idx2) = [listofwords{:}];

sep_cells = regexp(one_str,'_','Split');
out = reshape(str2double(sep_cells),N,[]).'./1000; %//'# desired output

方法 #3

现在,这个使用 sscanf 并且看起来非常快。这是代码-

N = 4; %// Edit this to 10 in your actual case
lens = cellfun(@numel,listofwords);
tlens = sum(lens);
idx(1,tlens)=0;
idx(cumsum(lens(1:end-1))+1)=1;
idx2 = (1:tlens) + cumsum(idx);

one_str(1:max(idx2)+1)='_';
one_str(idx2) = [listofwords{:}];
delim = repmat('%d_',1,N*numel(lens));
out = reshape(sscanf(one_str, delim),N,[])'./1000; %//'# desired output

基准测试

应@CST-Link 的要求,这是将他的“Kraken”eval方法 #3 进行比较的基准。基准测试代码看起来像这样 -

clear all

listofwords = repmat({'02_04_04_52_23_14_54_672_0'},100000,1);
for k = 1:50000
tic(); elapsed = toc(); %// Warm up tic/toc
end

tic
N = 9; %// Edit this to 10 in your actual case
lens = cellfun(@numel,listofwords);
tlens = sum(lens);
idx(1,tlens)=0;
idx(cumsum(lens(1:end-1))+1)=1;
idx2 = (1:tlens) + cumsum(idx);

one_str(1:max(idx2)+1)='_';
one_str(idx2) = [listofwords{:}];
delim = repmat('%d_',1,N*numel(lens));
out = reshape(sscanf(one_str, delim),N,[])'./1000; %//'# desired output
time1 = toc;
clear out delim one_str idx2 idx tlens lens N

tic
n_numbers = 1+sum(listofwords{1}=='_');
n_words = numel(listofwords);
listofwords_double = zeros(n_numbers, n_words);
for i = 1:numel(listofwords)
temp = ['[', listofwords{i}, ']'];
temp(temp=='_') = ';';
listofwords_double(:,i) = eval(temp);
end;
listofwords_double = (listofwords_double / 1000).';
time2 = toc;
speedup = ((time1-time2)/time2)*100;
disp(['Speedup with EVAL over NO-LOOP-SSCANF = ' num2str(speedup) '%'])

下面是代码运行几次后的基准测试结果 -

>> benchmark1
Speedup with EVAL over NO-LOOP-SSCANF = 0.30609%
>> benchmark1
Speedup with EVAL over NO-LOOP-SSCANF = 0.012241%
>> benchmark1
Speedup with EVAL over NO-LOOP-SSCANF = -2.3146%
>> benchmark1
Speedup with EVAL over NO-LOOP-SSCANF = 0.33678%
>> benchmark1
Speedup with EVAL over NO-LOOP-SSCANF = -1.8189%
>> benchmark1
Speedup with EVAL over NO-LOOP-SSCANF = -0.12254%

查看结果并观察到在一些积极的加速中有一些消极的加速(表明 sscanf 在这些情况下更好),我的意见是坚持使用 sscanf

关于performance - 将参数传递给 cellfun matlab,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26487246/

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