Aller au contenu
jjacques68

Optimisation traitement de chaines de caractères

Recommended Posts

hello tout le monde !

 

alors voilà, je reçois une chaîne de caractère de l'IPX (V3) comme celle-ci dès qu'une entrée/sortie/compteur change de valeur.

Citation

I=10000000000000000000000000000000&O=00000100000000010000000000000000&A0=0&A1=0&A2=0&A3=0&A4=0&A5=0&A6=0&A7=0&A8=0&A9=0&A10=0&A11=0&A12=0&A13=0&A14=0&A15=0&C1=1944716&C2=0&C3=0&C4=0&C5=0&C6=0&C7=0&C8=0

 

Comment peut-on traité la chaîne de manière la plus optimisée possible afin de ressortir les info suivantes :

 

  • la valeur de "C1"
  • les 12 premiers bits de "O"
  • les 8 premiers bits de "I"

 

actuellement j'utilise des fonctions de ce type : 

 

pour les Output : 

_Pos1, _ = string.find(value, "O=")
_GroupeBin = string.sub(value, _Pos1+2, _Pos1+2+11)

pour le compteur : 

_Pos1, _ = string.find(value, "C1=")
_Pos2, _ = string.find(value, "&C2")
string.sub(value, _Pos1, _Pos2-1))

et pire encore, quand je veux parcourir tous les bits des output un par un pour mettre à jour les QA (child) 

for i = 1, string.len(_GroupeBin) do
	if string.sub(_GroupeBin, i, i) == "1" then
	...
	else
	...
	end
end

 

Le soucis est que par exemple quand le compteur d'eau tourne, il me fait clignoter l'IN 1 environ 2 fois par seconde...

Donc j'ai minimum dans ce cas 2 trames à analyser par seconde... (sans compter l'incrémentation du compteur C1) 

Et la box calcule sévère avec ce genre de scripts...

ça marche très bien, c'est stable, mais je vois la CPU qui monte en flèche...

 

y a certainement moyen d'optimiser cela, mais j'avoue que je trouve pas grand chose...

 

Si vous avez des idées !!

 

merci à vous !!

 

 

 

Partager ce message


Lien à poster
Partager sur d’autres sites
Il y a 4 heures, jjacques68 a dit :

and even worse, when I want to cycle through all the bits of the output one by one to update the QA (child) 


 

Difficult.

local function test2()
  for i=1,#value do
    if string.sub(value,i,i) == "1" then
    else
    end
  end
end

local function test5()
  local n = value:len()
  local s = {value:byte(1,n)}
  for i=1,n do
    if s[i] == 49 then
    else
    end
  end
end

test5 is 50% faster for me - but you have to deal with byte values.

 

Is the data string you read always different? If not, cache seen data strings?

 

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Interesting ! to work with bytes ;) 

 

But datas change often.

They change depending from a I/O card.

All combinaisons are possible.

It will make a lot value in bytes to compare...

 

I ask myself with a binary mask maybe ? but I don't know how...

The position of the bit is important.

It's the number of the output...

Partager ce message


Lien à poster
Partager sur d’autres sites

au lieu de ça

for i = 1, string.len(s) do
	if string.sub(s, i, i) == "1" then
		...
	else
		...
	end
end

j'ai essayé ça

for i = 1, string.len(s) do
	if string.byte(s, i) == 49 then		--49 = "1" ; 48 = "0"
		...
	else
		...
	end
end

 

Mais je gagne vraiment pas grand chose en temps de traitement, là on parle de 0.020 ms de gains...

Est ce que c'est vraiment utile...

Partager ce message


Lien à poster
Partager sur d’autres sites
il y a 1 minute, jjacques68 a dit :

instead of that


for i = 1 , string . len ( s ) do if string . byte ( s , i ) == 49 then --49 = "1"; 48 = "0" ... else ... end end  

But I really don't gain much in processing time, here we are talking about 0.020 ms of gains ...

Is it really useful ...

No, string.byte is not that efficient (compared to .sub)

The difference I get is when I explode the string (with a single .byte call) and loop over the resulting byte array

local s = {value: byte (1, n)}
  for i = 1, n do
    if s [i] == 49 then ...

 

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites
il y a 6 minutes, jang a dit :

local s = {value: byte (1, n)}

I don't understand this syntax ?

 

 

Partager ce message


Lien à poster
Partager sur d’autres sites

I think I just understand

 

local s = {string.byte("10101010000000000000000000000000", 1, 32)}

It transforms a string in an array ? exactly ?

Modifié par jjacques68

Partager ce message


Lien à poster
Partager sur d’autres sites
9 minutes ago, jjacques68 said:

I think I just understand

 


   

It transforms a string in an array? exactly ?

Yes,

{<multiple value expression>} is a way to capture multiple return values in an array. string.byte returns 32 values in the example above.

function foo() return 3,5,7 end
local a = {foo()}
print(a[2])

 

Modifié par jang
  • Like 2

Partager ce message


Lien à poster
Partager sur d’autres sites

Yes !!!! I understand :) 

 

With this, I divide the processing time by 3 !!!

 

thaaaaanks a lot !!

Partager ce message


Lien à poster
Partager sur d’autres sites

×