integer strings decoding ... speed optimization

1 回表示 (過去 30 日間)
Michal
Michal 2017 年 11 月 13 日
コメント済み: Michal 2017 年 11 月 15 日
I have the following problem:
I need decode integer sequences "c" to char string messages "m" by following association:
numpos = 10 % ( = size(c,2)/2)
c = [3 4 1 1 4 2 5 2 3 3,1 1 1 1 2 2 2 3 3 3]
Each row of "c" represents 2*numpos integers, where first numpos parameters encoded position of
types = {'a' 'b@2' 'c@6' 'd@10' 'e@11'}
and second numpos parameters are applied only if type contains character '@' like this:
m = ' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'
My current solution is as follows:
function m = c2m(c,types)
numpos = size(c,2)/2;
F = cellfun(@(f) [' ' f], strrep(types,'@',':%d@'),'unif',0);
m = arrayfun(@(f,k) sprintf(f{1},k),F(c(:,1:numpos)),c(:,numpos+(1:numpos)),'unif', 0);
m = arrayfun(@(i) horzcat(m{i,:}), (1:numlines)', 'unif', 0)
end
and the testing code is as follows:
numlines = 10;
c = repmat([3 4 1 1 4 2 5 2 3 3,1 1 1 1 2 2 2 3 3 3],numlines,1);
types = {'a' 'b@2' 'c@6' 'd@10' 'e@11'};
m = c2m(c,types);
m =
10×1 cell array
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
The code is still too slow for me, I am looking for any speed up. In this case the most significant fraction of CPU time is spent at built-in function "sprintf".
Typical realistic sizes of problem are:
numpos ~ 30 ... 60
numlines ~ 1e4 ... 1e5
Any idea?

採用された回答

Michal
Michal 2017 年 11 月 15 日
編集済み: Michal 2017 年 11 月 15 日
Probably fastest and simplest solution, I found so far ... using latest new Matlab (>= R2016b) features, see function insertBefore and string datatype.
function m = c2m(c,types)
types = string(types);
numpos = size(c,2)/2;
a = c(:,1:numpos);
b = c(:,(numpos+1):end);
m = types(a);
m = insertBefore(m,"@", ":" + b);
m = join(m,2);
end
  2 件のコメント
Jan
Jan 2017 年 11 月 15 日
Does this consider that some types as "a" do not get an element of b?
Michal
Michal 2017 年 11 月 15 日
I am not sure, what do you mean exactly. Please clarify your question.

サインインしてコメントする。

その他の回答 (1 件)

Jan
Jan 2017 年 11 月 13 日
編集済み: Jan 2017 年 11 月 13 日
[EDITED] Consider all rows of c:
function m = c2m(c,types)
[s1, s2] = size(c);
numpos = s2 / 2;
m = cell(s1, 1);
typesF = strrep(types, '@', ':%d@'); % types to format specifiers
hasNum = ~strcmp(types, typesF); % true if the type has a '%d'
for im = 1:s1
c1 = c(im, 1:numpos);
c2 = c(im, numpos+1:end);
FmtSpec = sprintf(' %s', typesF{c1}); % Complete list of format specs
m{im} = sprintf(FmtSpec, c2(hasNum(c1))); % All c2, if c1 has a number spec
end
end
UNTESTED - I have no Matlab currently.
  4 件のコメント
Michal
Michal 2017 年 11 月 14 日
編集済み: Michal 2017 年 11 月 14 日
FmtSpec = CStr2String(typesF{c1}, ' ', 'noTrail');
should be
FmtSpec = CStr2String(typesF(c1), ' ', 'noTrail');
But the speed up with MEX file is only about a few percent.
Michal
Michal 2017 年 11 月 14 日
編集済み: Michal 2017 年 11 月 15 日
Jan, thanks a lot for your help. Your code is very good. Especially the fact, that the for-loop is possible to simple transform to parfor-loop to get some additional speed-up without any re-programming.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeGet Started with MATLAB についてさらに検索

タグ

製品

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by