>>>>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