Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matlab integer strings decoding ... speed optimization

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?

like image 714
michalkvasnicka Avatar asked Oct 27 '25 21:10

michalkvasnicka


1 Answers

In 16b MATLAB shipped some new text functions that make this easy. Also in 16b MATLAB shipped the new string datatype that makes this fast.

 function m = c2m_new(c,types, numlines)

     types = string(types);

     num_values = size(c,2)/2;

     a = c(:,1:num_values);
     b = c(:,(num_values+1):end);

     m = types(a);
     m = insertBefore(m,"@", ":" + b);
     m = join(m,2);
 end

>> 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'};
>> c2m_new(c,types,numlines)

ans = 

  10×1 string 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"

Looking at performance:

>> numlines = 1E4;
>> 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'};

% My solution
>> tic; for i = 1:10; c2m_new(c,types, numlines); end; toc
Elapsed time is 0.669311 seconds.

% michalkvasnicka's solution
>> tic; for i = 1:10; c2m(c,types, numlines); end; toc
Elapsed time is 23.643991 seconds.

% gnovice's solution
>> tic; for i = 1:10; c2m_gnovice(c,types, numlines); end; toc
Elapsed time is 8.960392 seconds.
like image 92
matlabbit Avatar answered Oct 29 '25 15:10

matlabbit



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!