Project hosted by SourceForge.net
 
 
xHarbour.com
 
xHarbour Optimizations

xHarbour Enhancements

String additions is more than 50 times faster than Harbour.

PCODE based optimized SubStr(), Left(), and Right() functions.

Much optimized code for FOR LOOPs, :=, +=, -=, -, +, when involving declared variables and numeric values.

Optimized WHILE .T. loops.

The underlying ITEM API has been rewritten (source/vm/fastitem.c) and is far faster and consumes much less memory.

Much extended Expression Optimizer produces faster code for common functions, and code notations. For example it will automatically convert:

aTail( <aArray> )        to aArray[-1]
SubStr( <cString>, X, 1 ) to cString[X]

which will execute much faster than the above common code.

Optimized generation of Line numbers and other similar optimizations which endup producing smaller and faster executables.

Built-in support for SET TRACE [On|Off] and TraceLog() function.

Optimized and extended Garbage Collector.

Optimized OOP system.

Full support for Clipper undocumented OOP internals (not available in Harbour).

Built-in support for OLE in Win32.

Enhanced aIns() and aDel() dismiss need for subsequent [common] aSize().

New HB_FuncPtr(), HB_ObjMsgPtr() and HB_Exec().

The xHarbour Run-time library was rewritten to take advantage of all above syntax extensions, and is taking full advantage of the resulting speed improvements.

As it stands at this point, xHarbour offers many syntax
extensions over Harbour and Clipper, including:

HASH Variable type:



Hashes are mainly arrays with non numerical keys

LOCAL hVar := Hash()
LOCAL hVar1 := { => } // Alternate hash declaration method.
LOCAL dDate := ctod( "02/01/2004" )

// complete charset & case sensitive
// string key support (case sens. can be turned on/off)
hVar[ e"first Key\n" ] := 10

// Date key support!!
hVar[ dDate ] := 20

// Non integer numerical key support
hVar[ 25.2 ] := 30

// Set operation support
hVar1 := hVar - { dDate => 0 } // removing dDate key

For more deails, see doc/hash.txt

XML Support:



hFile := FOpen( cFileName )

xmlDoc := TXmlDocument():New( hFile )
xmlNode := xmlDoc:oRoot:oChild
cXml := xmlNode:Path()

// there are methods to find nodes (but also attributes, values and data):
xmlNode := xmlDoc:FindFirstRegex( cNode )
// to modify them:
xmlNode:SetAttribute( "Name", "MyNode" )
// or to add them
xmlNode:InsertAfter( TXmlNode:New(HBXML_TYPE_TAG, "ANewNode" ) )

// and to write them back
hFile := FCreate( "output.xml" )
xmlDoc:Write( hFile )

More details in doc/hbxml.txt

Indirect execution support:


Other than codeblocks, xHarbour provides the inderect execution function
HB_ExecFromArray() that has the following syntax:

HB_ExecFromArray( cFuncName, [aParams] ) --> result
HB_ExecFromArray( @nFuncId(), [aParams] ) --> result
HB_ExecFromArray( bCodeBlock, [aParams] ) --> result
HB_ExecFromArray( oObject, cMethodName, [aParams] ) --> result
HB_ExecFromArray( oObject, nMethodID, [aParams] ) --> result
HB_ExecFromArray( aExecutableArray ) --> result

Other array parameter in HB_ExecFromArray past the function name or address,
the codeblock or the object and method identifier is directly passed as
that function, codeblock or method parameters (element 1 being the first
parameter and so on); the return of the function, codeblock or method,
if present, is returned.

An executable array is an array that has the elements structured as the other
HB_ExecFromArray function calls:

{ cFuncName, param1, ..., paramN }
{ @nFuncId(), param1, ..., paramN }
{ bCodeBlock, param1, ..., paramN }
{ oObject, cMethodName, param1, ..., paramN }
{oObject, nMethodID, param1, ..., paramN }

For more details, see doc/en/indirect.txt

Portable Service-like startup:



HB_Service( .T. )
puts the calling process in background.

HB_ServiceLoop()
Process some task in main application loop for non I/O based program (as services), like i.e. Windows messagehandling and GC collecting (can be used from any platform, it's duty varies from platform to platform).

STANDARD LOG sytem:



#include "hblog.ch"

INIT LOG [ON] ;
[FILE([nFilPrio [,cFileName[,nFileSize[,nFileCount] ] ] ] ) ] ;
[CONSOLE( [nConPrio] ) ] ;
[MONITOR( [nMonPrio [,nMonPort] ] ) ] ;
[SYSLOG( [nSysPrio [,nSysId] ] ) ] ;
[EMAIL ([nEmaPrio [,cHelo[,cServer[,cDest[,cSubject[,cFrom]]]]]])] ;
[DEBUG ( [nDebugPrio [,nMaxDebugPrio]] )] ;
[NAME cName]

LOG xVar1, ... , xVarn [PRIO[RITY] nPriorityLevel ]

CLOSE LOG

Read doc/hblog.txt for further details; hblog system has also a function API to access the standard logger and an object oriented custom log object support.

Protable signal and error handling system:


#include "hb_serv.ch"

HB_PushSignalHandler( nSignalMask, @SigHandler() )
HB_PushSignalHandler( nSignalMask, "SigHandlerFuncName" )
HB_PushSignalHandler( nSignalMask, {| aEvent | SigHandler Codeblock} )

In case any of the nSignalMask signals or error are received, the SigHandler function is called with an array of low level system dependant data.

HB_PopSignalHandler()

Removes a previously pushed signal hanlder.

HB_ServiceLoop()
Interprets some important Windows WM_ messages as signals to be handled by signal handlers.

See doc/hbsignal.txt for further details.

OOP Macros:


Objects now support macros:

Syntax:


- <Obj>:&Macro
- <Obj>:&Macro.Suffix
- <Obj>:&( <MacroExp> )

WITH OBJECT now supports macros:

Syntax:


- :&Macro
- :&Macro.Suffix
- :&( <MacroExp> )

Extended Literal Strings:


xHarbour introduces a new kind of literal strings known as "Extended Literal Strings".

Syntax:


E"..."

The literal string may contain Escape Codes following the C language conventions, like:

\n -> New Line character.
\t -> Tab character.
\r -> CR character.
\" -> literal <"> character.
\' -> literal <'> character.
\\ -> literal <\> character.

PERSISTENT Codeblocks:


Codeblocks may be persisted. Persisted Blocks must be restored within an Application containing the Compiled Module which the original Block was created at.

Syntax:


HB_SaveBlock( <Block> ) -> PersistedBlock Stream

HB_RestoreBlock( <PersistedBlock> ) -> Block

Module Scope:


OOP Scoping supports PRIVATE/HIDDEN, PROTECTED, and READONLY scopes. Classes sharing the SAME compilation unit may freely access such restricted access Members, without causing any scope violation.

Properties by Reference:


Instance Variables of Objects may be passed by REFERENCE to Functions and Methods.

Syntax:


SomeFunction( @<SomeObj>:<SomeVar> )

Associative Arrays:


Associative Arrays are like LITE Objects. Properties may be added on the fly without any declaration, much like new PRIVATE or PUBLIC can be created by simply assigning a value.

Associative Arrays, may use Objects Syntax (':' operator) or Array Index Syntax ('[]' operator) with the Property Name as the INDEX.

New Property will automatically be created upon first assignment.

Syntax:


<lValue> := TAssociativeArray()

<AA>[ "<NewProperty>" ] := <xValue>
<AA>:<NewProperty> := <xValue>

<AA>[ "<Property>" ]
<AA>:<Property>

SWITCH syntax:


SWITCH <Exp>
CASE <Constant>
...
[EXIT]

[More Cases ...]

[DEFAULT]
...
END

NOTE: This syntax is modeled after the C 'switch' flow control. It offers great speed benefit [30-300%] over DO CASE flow control, but is restricted to comparing only constants.

Constants may be: Integers, Longs, or Single Character Strings [much like in C]

WARNING: Those NOT familiar with the C switch flow control, should understand that unlike DO CASE, you MUST explicitly use the EXIT statement or else logic will FALL THROUGH to the NEXT CASE, until stopped at a EXIT, or END statements.

At first this might seem VERY ODD, but it provides great flexibility exactly like the C model.

See tests/switch.prg to for a sample and to learn how the FALL-THROUGH logic works.

Multi Threading (MT) Support:


xHarbour supports MT applications. There is still some more work to be done, but you can already take advantage of this very powerful feature.

Basic sample can be found at:

tests/mttest.prg

Syntax:


StartThread ( @MyThreadFunc() [, xParam1 [,xParamN ] ] )

Syntax:


CRITICAL [STATIC] FUNCTION|PROCEDURE( [xParam1 [, xParamN ] ] )

NOTE: MT Application must link against the MT versions of the Libraries, i.e. vmmt.lib, rtlmt.lib, ppmt.lib, rddmt.lib, dbfntxmt.lib, and dbfcdxmt.lib.

The full description of MT is beyond the scope of this document; see more in doc/thread.txt and doc/xhbt_internals.txt

Portable Sockets Support:


LOCAL Socket

Socket := InetConnect( "www.host.com", nPort )
Socket := InetSend( "Hello from me" )
InetClose( Socket )

The full description is beyond the scope of this document; see doc/inet.txt for further details.

Perl-5 compatible RegEx:


xHarbour includes PCRE which is a full feature, Perl 5 compatible, Regular Expression engine. Full feature Search & Replace classes are currently under construction, but you may already use the full power of RegEx searches, new operators, HAS and LIKE.

cExp HAS cPatern|RegEx => bFound
cExp LIKE cPatern|RegEx => bLike

As well as full featured Functions:

HB_Atx( <cRegEx>, <cTargetString> [, lCaseSensitive [, [@]nStart ]
[, [@]nLen ] ] ] ) => cFoundText

RegexComp( cPattern, [bCaseSens [, bNewLine]] ) --> REGEX

HB_Regex( cPattern, cString, [bCaseSens, [, bNewLine]] ) --> aMatches

HB_RegexMatch( cPattern, cString, [bCaseSens, [, bNewLine]] ) --> bFound

TRY syntax:


TRY
...
[THROW( <Exp> )]
...
CATCH <Id>
...
END

The above is very similar to Clipper BEGIN SEQ, BREAK(), RECOVER USING, END, but is more inline with more "modern" languages, and dismisses the need to worry about Error Codeblock.

IN operator:


<Exp> IN <Array_or_StringExp> => .T./.F.

The IN operator is very similar to the $ operator, but is valid on *both* Strings and Arrays. IN is much faster than the equivalent:

aScan( <Array>, <Exp> ) > 0

Variable Parameters syntax:


Function <cFuncName>( ... )

The above definition allows this Function to receive up to 254 parameters.
You may retrieve an ARRAY with all the parameters using:

HB_aParams()

The above is appropriate for such functions that may receive any number of generic parameters, which normally will then be processed in a loop, or with hard coded IF statements based on PCount(). Instead the above is much easier to code, requires less memory, and is faster than declaring the parameters.

GLOBAL variables:


GLOBAL <Id1> [,<Id2> [,<IdN>]]

GLOBAL Variables are a new kind of a declared variables. They have PUBLIC like visibility, but are faster than even STATICs. GLOBALs can be referenced from other modules.

Syntax:


GLOBAL EXTERNAL <Id1> [,<Id2> [,<IdN>]]

GLOBAL Variables have the added benefit of being *directly* accessible from C code too.

True C Type Structures:


C STRUCTURE <strucName> [Align <align>]
[ MEMBER <memberName> IS <CTYPEDEF> ]
[ MEMBER <memberName[<arrayLength>]> IS <CTYPEDEF> ]
[ MEMBER <memberName> IS <CTYPEDEF>(<arrayLength>) ]
[ MEMBER <memberName> IS|INPLACE <strucName> ]
[ MEMBER <memberName> AS <strucName> ]
[ ... ]
END C STRUCTURE

C Structure can be passed *directly* TO and FROM C code. The full description is beyond the scope of this document - please refer to cstruct.txt in doc folder.

WITH OBJECT syntax:


WITH OBJECT <exp>
...
:<exp>
...
END

HB_QWith() can also be used to retrieve the current WITH OBJECT within a WITH OBJECT block.

HB_SetWith() may be used to SET or RESET the value of the WITH OBJECT from an expression, much like the WITH OBJECT construct.

The above syntax not only saves typing, but is also MUCH faster than equivalent conventional coding.

FOR EACH Syntax:


// <ElementOrProperty> must be a declared variable.
FOR EACH <ElementOrProperty> IN <ArrayOrObject>
// ElementOrProperty holds value of each respective element or property.
<ElementOrProperty>
HB_EnumIndex() // Returns current Position Index.
[LOOP]
[EXIT]
NEXT

The FOR EACH syntax is not only more elegant than:

FOR Counter := 1 TO Len(Array)
Element := Array[Counter]
...
NEXT

but is also MUCH faster - and it also supports enumerating all properties in an object.

Full access to OLE Servers:


CreateObject( "ServerName" ) => oOleObject
Create new instance of an Ole Server.

GetActiveObject( "ServerName" ) => oOleObject
Get existing instance of an Ole Server.

All documented methods and properties of such Server should be directly accessible.

Strings may be indexed like arrays:


<StringExp>[<IndexExp>]

String as Array Index can also accepts a numeric as an assigned value:

<StringExp>[<IndexExp>] := 65 // Same as := 'A'

String Index and all Strings of 1 character length automatically carry a secondary CHAR type, which means they are also compatible with numeric operations.

cVar := "hello"; cVar[1] -= 32 // -> "Hello"

Negative Array Index:



Both Arrays and Strings may be indexed with negative numbers (Reversed), where -1 indexes the LAST Element (or NIL if the Array is empty):

cVar[-1] // => "o"

// assuming cVar is the value "Hello" as per above.

#[x]uncommand and #[x]untranslate directives:


#uncommand and #untranslate directives allow the removal of a given rule from the active rules used by the Pre-Processor. It is very much like the #undefine directive.

Extended macro support:


&cMacro.<suffix>

will compile correctly even if cMacro is a declared var.

Optimizations:


String additions is more than 50 times faster than Harbour.

PCODE based optimized SubStr(), Left(), and Right() functions.

Much optimized code for FOR LOOPs, :=, +=, -=, -, +, when involving declared variables and numeric values.

Optimized WHILE .T. loops.

The underlying ITEM API has been rewritten (source/vm/fastitem.c) and is far faster and consumes much less memory.

Much extended Expression Optimizer produces faster code for common functions, and code notations. For example, it will automatically convert:

aTail( <aArray> ) to aArray[-1]
SubStr( <cString>, X, 1 ) to cString[X]

which will execute much faster than the above common code.

Optimized generation of Line numbers and other similar optimizations which end up in producing smaller and faster executables.

Built-in support for SET TRACE [On|Off] and TraceLog() function.

Optimized and extended Garbage Collector.

Optimized OOP system.

Full support for Clipper undocumented OOP internals (not available in Harbour).

Built-in support for OLE in Win32.

Enhanced aIns() and aDel() dismiss need for subsequent [common] aSize().

New HB_FuncPtr(), HB_ObjMsgPtr() and HB_Exec().

The xHarbour Run-Time library was re-written to take advantage of all above syntax extensions, and is taking full advantage of the resulting speed improvements.

Fixed:


HB_Qself() returns correct QSelf() even from inside Codeblocks (inline methods).

@ x,y GET &xMacro.Suffix
-> Clipper complains: Error C2081 Macro of declared symbol.

@ x,y GET &( xMacro )
-> Clipper complains: Error C2047 GET contains complex macro.

@ x,y GET &( xMacro )[...]
-> Clipper complains: Error C2047 GET contains complex macro.

xHarbour is about twice as fast as Clipper on most common operations [excluding console screen output and DBF access], and about 25% to 1000% faster than Harbour.

xHarbour should compile and execute all valid Clipper and Harbour code, without any modifications - such code will be automatically optimized to take advantage of xHarbour extensions.

 

 
   
© 2024 xHarbour.org. All rights reserved.
Contact us | Terms of Use Agreement
xHarbour.ORG is maintained by Enrico Maria Giordano
Internet services kindly provided by Bekz.net