Convert long Hex String to array of uint16

48 visualizaciones (últimos 30 días)
Oren Lee
Oren Lee el 13 de Nov. de 2018
Comentada: Oren Lee el 13 de Nov. de 2018
Hi,
I am importing TONS of data that is being sent to be as a long sequence of Hex values (see temp below). In this data stream is a mix of data sampled at a variety of different rates, and positioned sequentially in this string (all this I have a decoder for).
What I am hoping to try and speed up is the scan of the string below. For example, I want to quickly grab the first 512 characters below and convert them to a [1x128] array of uint16's (the following 512 perform the same thing and so on).
Currently, it takes me ~3.7 seconds to fully scan the string included below (using the code below). This is unacceptable since I need to be going through ~1,000,000 of them per batch. I have played around in MATLAB a LOT, but don't have a CS background and was hoping someone would have an idea of what needs to be done to try and speed this up. A snapshot of my code is given below. This whole sequence needs to hopefully become ~1/100 which is beyond my expertise in trying to save time.
Not included in the code below, but I am iterating over ~13,000 strings of the same size and parameter structure to temp below (which are all included per file). Perhaps there is a way to include into one loop as to speed things up as well.
Any help is appreciated! Thanks!
temp = ['b0a0b5d4b595b1bbb47eac72b1c0bf0cbcbbbdfebcd5bbd0b719b694b6b5c98eca84c9ecc933ca2ecb66c746c8c9c641bb8bb66bba06bd83b518c931c2ebc4fac576...' ...
'c6bdf9d9fd71fd22c0bdc78cc815fffffffffffffc46fff0fc45ffffffffff100020003300000123610200200000000fffff000000000000000150000fff00ff0000000fffffffff0' ...
'fff0fffffff01236102000100000005ffffffff0000012361020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' ...
'00000000000000000000000000000000000000000000000000000000000000000000000000000000000000'];
% Not provided is COM which is a somplex structure defining where all the parameters lay in the above string.
% COM.Content{j} is the current parameter, and COM.Content{j}.RunningOffset,COM.Content{j}.Occurances provide the details of where each parameter lies.
% See attached file for COM variable
% Parameters are NOT necessarilly in order unfortunately.
for j = 1:length(COM.Content) %iterate over each parameter
curParam = COM.Content{j};
curOffset = curParam.RunningOffset*4-3;
curEnd = curParam.RunningOffset*4-4 + curParam.Occurrences*4;
sIdx=1;
eval([curParam.Name,'=zeros(1,length(temp)/4);']); % I want to save each param as it's own param name which is done here
for k = 1:length(temp)/4 % I was hoping to avoid an for loop, but couldn't see a way aruond this
eval([curParam.Name,'(',num2str(k),')='...
'sscanf(temp(',num2str(4*k-3),':',num2str(k*4),'),''%x'');']); % I found sscanf to be a touch faster than hex2dec (3.85s vs 3.70s)
end
end
  2 comentarios
Stephen23
Stephen23 el 13 de Nov. de 2018
Editada: Stephen23 el 13 de Nov. de 2018
Avoid using eval to create variable names. Magically acessing variable names is one way that beginners force themselves into writing slow, complex, buggy code. Read this to know why:
Basic MATLAB indexing is much simpler, neater, easier to debug, and much more efficient.
Oren Lee
Oren Lee el 13 de Nov. de 2018
Thanks for the tip, and has been implemented in my code now and something I'll keep in mind for the future.

Iniciar sesión para comentar.

Respuesta aceptada

James Tursa
James Tursa el 13 de Nov. de 2018
Editada: James Tursa el 13 de Nov. de 2018
Not sure exactly what you need, but here is an approach that turns a temp string of hex digits into a vector of uint16 values (4 hex digits per value):
temp = your char string of hex digits (numel a multiple of 4)
u = uint16(hex2dec(reshape(temp,4,[])'));
And don't use eval( ) to create variable names on the fly. It is better to use cell arrays for this. That way you can use normal indexing to set and get the variables instead of using more eval( ) constructs downstream in your code.
  1 comentario
Oren Lee
Oren Lee el 13 de Nov. de 2018
Wow! great tip on reshape(), really did the trick! This coupled with the comment on my question above (regarding not using eval() ) really did the trick! That alone dropped things to 0.33s per string!

Iniciar sesión para comentar.

Más respuestas (1)

Walter Roberson
Walter Roberson el 13 de Nov. de 2018
t = temp - '0';
mask = t>9;
t(mask)=t(mask)-39;
out = t(1:2:end)*16+t(2:2:end);

Community Treasure Hunt

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

Start Hunting!

Translated by