Filter löschen
Filter löschen

Convert long Hex String to array of uint16

39 Ansichten (letzte 30 Tage)
Oren Lee
Oren Lee am 13 Nov. 2018
Kommentiert: Oren Lee am 13 Nov. 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 Kommentare
Stephen23
Stephen23 am 13 Nov. 2018
Bearbeitet: Stephen23 am 13 Nov. 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 am 13 Nov. 2018
Thanks for the tip, and has been implemented in my code now and something I'll keep in mind for the future.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

James Tursa
James Tursa am 13 Nov. 2018
Bearbeitet: James Tursa am 13 Nov. 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 Kommentar
Oren Lee
Oren Lee am 13 Nov. 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!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Walter Roberson
Walter Roberson am 13 Nov. 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