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 09:41:02
 
 
À
Tous
Information générale
Forum:
Visual FoxPro
Catégorie:
Autre
Titre:
A simple test show VFP string concat optimization
Divers
Thread ID:
00862123
Message ID:
00862123
Vues:
49
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
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform