Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
A simple test show VFP string concat optimization
Message
De
26/12/2003 10:03:28
 
 
À
26/12/2003 09:41:02
Information générale
Forum:
Visual FoxPro
Catégorie:
Autre
Divers
Thread ID:
00862123
Message ID:
00862130
Vues:
8
Hi Fabio,

I think vfp optimizes (pseudo code)

str = str + 'something'
to
oldlen = str.val.ev_length 
_SetHandSize(str.val.ev_handle, str.val.ev_length + len('something'))
_HLock(str.val.ev_handle);
strptr = (char *)_HandToPtr(str.val.ev_handle) + oldlen
strcat(strptr, "something")
_HUnLock(str.val.ev_handle);
whereas with stuff it it creates a new result string
str = stuff( str, ......)

Gregory
_______________________
>Hi,
>
>VFP do not have a optimization to thread a string like a char* array in C or C++.
>
>The candidate function for do this is STUFF():
>
>myString = STUFF(m.myString , iPosition , replaceLenght,sReplace) && with LEN(sReplace) = replaceLenght
>
>
>If VFP recognize this pattern and use a on place stuffing,
>string ( and surrogate C structure for DLL ) using can speed up by 1 to 1000000 or more. But for now VFP do not recognize this.
>
>Hovewer, VFP virtual machine have a little optimization for string concatenation.
>
>This test show it:
>
>CLEAR
>SET ESCAPE ON
>
>DECLARE INTEGER QueryPerformanceCounter IN kernel32.DLL;
>  STRING @lpPerformanceCount
>
>DECLARE INTEGER QueryPerformanceFrequency IN kernel32;
>  STRING @lpFrequency
>
>STORE REPLICATE(CHR(0), 8) TO lcbuffer1,lcbuffer2
>
>IF QueryPerformanceFrequency(@m.lcbuffer1) = 0
>  ? "High-resolution performance counter not supported on your system"
>  RETURN
>ENDIF
>
>lnfrequency = large2num(@m.lcbuffer1)
>
>** next cycle to force CENTRINO 100% performance
>
>FOR j=0 TO 10000000
>NEXT
>
>ON ERROR
>
>? 'lenght',	"		ss = m.ss +'' "	, 	"		= m.ss "	, 	"		ss = m.ss ", 	"	STORE m.ss TO ss "
>lenght = 1
>DO WHILE m.lenght < 15000000
>	myString =replicate('a',m.lenght)
>	?  m.lenght
>
>	=queryperformancecounter(@M.lcbuffer1)
>
>	FOR j=0 TO 1000000
> 		myString = m.myString + ''
>	NEXT
>
>	queryperformancecounter(@M.lcbuffer2)
>	
>	?? TRANSFORM(m.lnfrequency*m.j/(large2num(@m.lcbuffer2)-large2num (@m.lcbuffer1)),'@R 999,999,999,999 ops/s')
>
>	*****
>	=queryperformancecounter(@M.lcbuffer1)
>
>	FOR j=0 TO 1000000/m.lenght
>		 = m.myString
>	NEXT
>
>	queryperformancecounter(@M.lcbuffer2)
>
>	?? TRANSFORM(m.lnfrequency*m.j/(large2num(@m.lcbuffer2)-large2num (@m.lcbuffer1)),'@R 999,999,999,999 ops/s')
>
>	*****
>	=queryperformancecounter(@M.lcbuffer1)
>
>	FOR j=0 TO 1000000/m.lenght
>		 myString = m.myString
>	NEXT
>
>	queryperformancecounter(@M.lcbuffer2)
>
>	?? TRANSFORM(m.lnfrequency*m.j/(large2num(@m.lcbuffer2)-large2num (@m.lcbuffer1)),'@R 999,999,999,999 ops/s')
>
>	*****
>	=queryperformancecounter(@M.lcbuffer1)
>
>	FOR j=0 TO 1000000/m.lenght
>		 STORE m.myString TO myString
>	NEXT
>
>	queryperformancecounter(@M.lcbuffer2)
>
>	?? TRANSFORM(m.lnfrequency*m.j/(large2num(@m.lcbuffer2)-large2num (@m.lcbuffer1)),'@R 999,999,999,999 ops/s')
>
>
>	m.lenght = m.lenght * 10
>enddo
>return
>
>FUNCTION  large2num (lcbuffer)
>  RETURN buf2dword(LEFT(m.lcbuffer, 4)) + buf2dword(RIGHT(m.lcbuffer, 4)) * 0x100000000
>
>FUNCTION  buf2dword (lcbuffer)
>  RETURN	ASC(m.lcbuffer)							;
>  	+ 		ASC(SUBSTR(m.lcbuffer, 2,1)) * 256		;
>    +		ASC(SUBSTR(m.lcbuffer, 3,1)) * 65536  	;
>    + 		ASC(SUBSTR(m.lcbuffer, 4,1)) * 16777216
>
>
>The myString = m.myString + '' is the optimized concatenation;
>VFP recognize the
>myString = m.myString + pattern, and use a different concatenation algorithm;
>if the added string have zero bytes, it passes beyond without making null.
>
>Because the optimization is done at runtime, and is memoryless, the optimized code
>have a overhead, and for small string it is slower respect to a not optimized concatenation.
>
>If VFP recognize this optimizable function at compile time, this overhead not there would be.
>
>Fabio
Gregory
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform