Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Speeding up string conversion
Message
From
16/03/2005 09:06:28
 
 
To
16/03/2005 08:47:32
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
00996197
Message ID:
00996288
Views:
34
>>>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
>>
>>This thread is a interesting point for publishing the only solution
>>that can reduce the VFP long string processing, without write a C code.
>>The solution is not immediate, because it is RECURSION.
>>The problem of VFP with a strings and native command is that into
>>a native command is not possible pass a var by reference ( a mem pointer ),
>>then VFP copy the string into a engine buffer.
>>With Recursion you can create of the virtual pointer, breaking the string in substring,
>>this have another important effect, VFP move and work on short string, then the
>>job is done in first level cache
>>( the only area of memory where the cpu efficiency works is sufficient ).
>>
>>On next code, STRCONV() return a the expected time for a C implementation
>>Then:
>>
>>#DEFINE MAXLEN 2048
>>
>>X=''
>>FOR K=0 TO 255
>> X=X+CHR(K)
>>NEXT
>>ACTIVATE WINDOW "Debug Output"
>>DEBUGOUT toBYTEA(REPLICATE(m.x,100))== toBYTEA3(REPLICATE(m.x,100))
>>FOR j=2 TO MAXLEN STEP 0
>>	T0=SECONDS()
>>	=toBYTEA(REPLICATE(m.x,m.j))
>>	t1=SECONDS()-T0
>>	T0=SECONDS()
>>	=toBYTEA2(REPLICATE(m.x,m.j))
>>	t2=SECONDS()-T0
>>	T0=SECONDS()
>>	=toBYTEA3(REPLICATE(m.x,m.j))
>>	t3=SECONDS()-T0
>>	T0=SECONDS()
>>	=STRCONV(REPLICATE(m.x,m.j),15)
>>	t4=SECONDS()-T0
>>	DEBUGOUT m.j,m.t1,m.t2,m.t3,M.T4
>>	j=j*2
>>NEXT
>>
>>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
>>
>>FUNCTION toBYTEA2( cStr )
>>
>>	STORE STRTRAN(STRTRAN(m.cStr,[\],[\\134]),['],[\\047]) TO cStr
>>	PRIVATE nChr
>>	FOR nChr=0 TO 255
>>		IF m.nChr=32
>>			STORE 126 TO nChr
>>			LOOP
>>		ENDIF
>>		STORE STRTRAN(m.cStr;
>>				,	CHR(m.nChr);
>>				,	'\\'+ CHR(48+ BITAND(m.nChr/64,7))+CHR(48+ BITAND(m.nChr/8,7))+CHR(48+ BITAND(m.nChr,7)));
>>			TO cStr
>>	NEXT
>>	RETURN m.cStr
>>ENDFUNC
>>
>>FUNCTION toBYTEA3( cStr,lenght )
>>	IF PARAMETERS()=1
>>		* this is a slow op
>>		STORE LEN(m.cStr) TO lenght
>>	ENDIF
>>	IF m.lenght>100
>>		* this is a slow op
>>		RETURN	toBYTEA3(LEFT( m.cStr ,BITRSHIFT(m.lenght+1,1)) ,BITRSHIFT(m.lenght+1,1))	;
>>			+	toBYTEA3(RIGHT(m.cStr ,BITRSHIFT(m.lenght,1))   ,BITRSHIFT(m.lenght  ,1))
>>	ENDIF
>>	PRIVATE cRes, cChr
>>	STORE [] TO cRes
>>	FOR lenght=1 TO m.lenght
>>		* this is a slow op
>>		STORE SUBSTR( m.cStr, m.lenght,1)	TO cChr
>>		* this is a fast op
>>		cRes = m.cRes + IIF(BETWEEN( ASC( m.cChr), 32,126 ) AND !INLIST( ASC( m.cChr),39,92);
>>	  			,	m.cChr	;
>>	  			,	'\\'+ CHR(48+ BITRSHIFT(ASC(m.cChr),6))+CHR(48+ BITAND(BITRSHIFT(ASC(m.cChr),3),7))+CHR(48+ BITAND(ASC(m.cChr),7)))
>>	ENDFOR
>>	* this is a slow op
>>	RETURN m.cRes
>>ENDFUNC
>>
>>
>>Fabio
>
>hi Fabio,
>
>A1 = dog slow
>A3 = recursion, faster
>A2 = the fastest ( it resembles the code I have posted)

Mistery.
My results:
.T.
         2          0,000          0,010          0,000          0,000
         4          0,010          0,010          0,000          0,000
         8          0,010          0,030          0,010          0,000
        16          0,020          0,060          0,020          0,000
        32          0,051          0,120          0,030          0,000
        64          0,170          0,240          0,080          0,000
       128          0,601          0,491          0,160          0,000
       256          1,923          1,072          0,320          0,000
       512          7,271          2,583          0,591          0,000
      1024         22,112         16,484          1,171          0,000
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform