Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Speeding up string conversion
Message
De
16/03/2005 08:16:15
 
 
À
16/03/2005 08:03:12
Information générale
Forum:
Visual FoxPro
Catégorie:
Codage, syntaxe et commandes
Divers
Thread ID:
00996197
Message ID:
00996264
Vues:
16
>>>>I need to convert binary strings to ascii by changing nonprintable non-ascii
>>>>charaters to a \\nnn strings where nnn is octal representation.
>>>>
>>>>I created the following routine. For 381 KB byte strings, the conversion takes 5 (!) minutes and task manager shows that my application takes a lot of MBs memory.
>>>>
>>>>Any way to speed up this conversion ?
>>>>
>>>>
FUNCTION toBYTEA( cStr )
>>>>
>>>>LOCAL i, j, cRes, nChr, cDig
>>>>
>>>>cRes = ''
>>>>FOR i=1 TO LEN(m.cStr)
>>>>  nChr = ASC( SUBSTR( m.cStr, m.i,1))
>>>>  * The following four lines cna be removed if this can speed the conversion.
>>>>  IF BETWEEN( nChr, 32,126 ) AND !INLIST( nChr,39,92)
>>>>    cRes = m.cRes + SUBSTR( m.cStr, m.i,1)
>>>>    LOOP
>>>>    ENDIF
>>>>
>>>>  cDig = ''
>>>>  FOR j=1 TO 3
>>>>    cDig= CHR(ASC('0')+ m.nChr%8) + m.cDig
>>>>    nChr = INT(m.nChr/8)
>>>>    ENDFOR
>>>>  cRes = m.cRes + '\\'+ m.cDig
>>>>  ENDFOR
>>>>RETURN m.cRes
>>>>ENDFUNC
>>>
>>>Andrus,
>>>
>>>VFP's code optimization is near to zero.
>>>
>>>With your code VFP copy the 381KB string
>>>1+381KB*(1+x+0.5+)=381000 ..780000 times
>>>Then VFP move more of 150..304GB !
>>>
>>>Until a VFPM (Calvin Hsia ? ) implement a @m.string reference for VFP commands
>>>all VFP programs with large string suffer of this problem.
>>>
>>>This can reduce the time ( put m. everywhere )
>>>
>>>FUNCTION toBYTEA( cStr )
>>>
>>>	PRIVATE i,  cRes, cChr, nChr
>>>
>>>	cRes = ''
>>>	FOR i=1 TO LEN(m.cStr)
>>>		STORE SUBSTR( m.cStr, m.i,1)	TO cChr
>>>		STORE ASC( m.cChr)				TO nChr
>>>		cRes = m.cRes + IIF(BETWEEN( m.nChr, 32,126 ) AND !INLIST( m.nChr,39,92);
>>>	  			,	m.cChr	;
>>>	  			,	'\\'+ CHR(48+ BITAND(m.nChr/64,7))+CHR(48+ BITAND(m.nChr/8,7))+CHR(48+ BITAND(m.nChr,7)))
>>>	ENDFOR
>>>	RETURN m.cRes
>>>ENDFUNC
>>>
>>>
>>>your Vfp VERSION ?
>>
>>hi Fabio,
>>
>>I agree for the m. prefix
>>
>>Still, I'd say that appending a byte to a string 381 k times, is really slowing it down
>
>>
>>The string has to be reallocated/expanded 381k times
>
>Hi Gregory,
>
>This is not true. VFP alloc 100 bytes blocks for the string,
>and if next heap memory is free, it merge it into the string without realloc it.
>Result, realloc occur very rarely.
>
>>Bytes moved totally = (381*1024) * (381*1024+1) / 2 is about (381*1024)^2/2 or over 72 Gb (if the string is not expanded at the same place in memory)
>>
>>
>>The StrTran() approach works faster imo
>>
>>I get for a worst case (repl(chr(0), 381*1024)) less than 13 sec with strtran() where the string is reallocated 163 times
>
>STRTRAN is a global command.
>With it VFP have to:
>- scan it ALL
>- if found a string it replace it, BUT if the new substring have lenght upper to the old substring,
>then VFP have TO MOVE the right string ! this is a intensive task, and set the alghoritm to O(n*n) complexity
>
>These two issues create one disastrous consequence:
>- if the string where the program worked it does not remain in the first level cache, the performances collapse
>
>Read my 2th Message to Andrus, for a best solution,
>however it's efficiency if of 0.1% respect to a C code.
>
>Fabio


hi Fabio,

I understand that if the string is reallocated in place that there is no memory movement

I did not see your 2nd message to Andrus, and can you explain the following:

Why is a strtran() that is being executed 163 times for a worst case scenario so much faster than the routine you posted to Andrus (1st message)

If I'm allowed a guess, I'd say the strtran() builds an output buffer, reads from the input, and copies to the output, ie copy the whole input rather than moving chars to the right
Gregory
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform