pbugg meeting, may 2006 - copyright by arnd schmidt1 powerbuilder and c++ or how to optimize...

33
PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst [email protected]

Upload: lee-tyler

Post on 27-Dec-2015

225 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 1

PowerBuilder and C++

or

How to optimize excessive string operations

Arnd Schmidt

system analyst

[email protected]

Page 2: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 2

PowerBuilder and C++ - Abstract

• Abstract– PowerBuilder and Strings– A simple of_ReplaceAll ()– Setting up a test suite– Install OpenWatcom C++– Simple DLL Example for OpenWatcom– Install Visual Studio Express C++– Simple DLL Example for Visual C++– A faster of_ReplaceAll () in OpenWatcom– Accessing Functions and Classes– PowerBuilder Native Interface (PBNI)– Live demonstrations and Labs

Page 3: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 3

PowerBuilder Strings – The String

Q: What is a string? A: A sequence of characters in memory,

delimited by a special character.What else should be a ”Zeichenkette”?

Q: What is that special character?A: That is the null byte (0x00).

Q: Are there any string length limitations? A: Yes, it is limited by the (available) memory.

Page 4: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 4

Variable ls_test holds the address of the strings first character.Representation in Memory:

PowerBuilder Strings – Memory Usage (ANSI)string ls_test = ”PowerBuilder”

H e u t e :

P o w e r B u i l d e r

M o r g e n :

50 6F 77 65 72 42 75 69 6C 64 55 72 00

Representation in Memory (Hexadecimal):

Page 5: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 5

PowerBuilder Strings – ASCII Table

ASCII Table (00-7F):

0 1 2 3 4 5 6 7 8 9 A B C D E F

0 NUL SOH STX EXT EOT ENQ ACK BEL BS HT LF VT FF CR SO SI

1 DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US

2 SP ! " # $ % & ' ( ) * + , - . /

3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?

4 @ A B C D E F G H I J K L M N O

5 P Q R S T U V W X Y Z [ \ ] ^ _

6 ` a b c d e f g h i j k l m n o

7 p q r s t u v w x y z { | } ~ DEL

Page 6: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 6

• UTF-8– variable-width encoding of Unicode (1-3 byte)

• UTF-16 (UCS-2)– fixed-width encoding (2 byte)– UTF-16LE (Little Endian)– UTF-16BE (Big Endian)– Default: UTF-16LE

PowerBuilder Strings – Unicode

Example: Character ’P’ (0x50)

Offset 0 1

UTF-16LE 50 00

UTF-16BE 00 50

Page 7: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 7

PowerBuilder Strings – UTF16 (UCS-2)

Examples of used ranges:

Range Name Examples

0020-007F Basic Latin 0-9,A-Z,a-Z,!,$,%,<,=,>, ...

00A0-00FF Latin 1 SupplementedÀ, Ä, Ë, Ö, Ü, ä,ö,ü,ß, ©, ..

0100-017F Latin Extended A Ą, ą, Ę, ę, Ģ, ģ

0180-024F Latin Extended B Ǎ, ǎ, Ǽ, ǽ, Ǿ, ǿ

0370-037F Greek and CopticΑ, Β, Γ, Δ, Ε, α, β, γ, δ, ε

0600-06FF Arabic ٤, ٣, ٢, ١, ٠, ل, ض, ص ,

Page 8: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 8

Variable ls_test holds the address of the strings first character.Representation in Memory:

PowerBuilder Strings – Memory Usage (Unicode)string ls_test = ”PowerBuilder”

P o w e r b u i

l d e r

50 00 6F 00 77 00 65 00 72 00 42 00 75 0069

00 6C 00 64 00 55 00 72 00 00 00

Representation in Memory (Hexadecimal):

Page 9: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 9

PowerBuilder Strings – Functions

• Built-in functions:– Char (), Fill (), Space ()– ASC (), Lower (), Upper (), Reverse () , Wordcap ()– Trim (), LeftTrim (), RightTrim ()– Len (), Pos (), LastPos()– Mid (), Left (), Right (), – Replace () – Match ()

Prior PB10: Functions like LenW() for Unicode supportSince PB10: Functions for 1-byte character support like LenA ()

Page 10: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 10

PowerBuilder Strings – A simple of_ReplaceAll () Function• Lab 1 (5 min.)

Implement the function of_ReplaceAll () that will– Replace all occurrences of the string as_old in a given

string as_source by the string as_new.– Return the modified as_source.

Test the function by coding:string ls_testls_test = & of_ReplaceAll (”ABAABAABAAABA”,”ABA”,’A”)

Value of ls_test should be: ”AAAAA”

Page 11: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 11

PowerBuilder Strings – Example Code for a simple of_ReplaceAll ()

Function String of_ReplaceAll( String as_source, String as_old, String as_new )long ll_Pos = 1// Find the first occurrence of as_old ...ll_Pos = Pos ( as_source, as_old, ll_Pos )

// Only enter the loop if you find as_old ...Do While ll_Pos > 0 // Replace old_str with ls_new_str ... as_source = Replace ( as_source, ll_Pos, Len(as_old), as_new)

// Find the next occurrence of ls_old_str ll_Pos = Pos ( as_source, as_old, ll_Pos + Len(as_new))Loop// Return stringReturn as_source

Possible Implementation:

Page 12: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 12

PB Strings – Discussion

• What happens during execution for large strings with a lot of replacements?– Due to string assignments there will be a lot

of memory related operations (allocation and copying).

– The Len () function will be called to much, even though the strings (old/new) are usually not very long.

Page 13: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 13

PowerBuilder Strings – Case sensitive/ insensitive of_ReplaceAll ()• Lab 2 (5 min.)

Expand the function of_ReplaceAll () to accept a boolean variable so that it works case sensitive or case insensitive.– Replace all occurrences of the string as_old in a given

string as_source by the string as_new.– If the functions boolean argument ab_ignorecase is set

to true, perform the search case insensitive.– Return the modified as_source.

Test the function by coding:string ls_testls_test = & of_ReplaceAll (”ABaabAaBaaABa”,”aBA”,”a”, True)

Value of ls_test should be: ”aaaaa”

Page 14: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 14

PowerBuilder Strings – Example Code for a case insensitive of_ReplaceAll ()

Function String of_ReplaceAll( String as_source, String as_old, String as_new Boolean ab_ignorecase )Long ll_pos // Position of as_old in as_sourceLong ll_oldLen // Length of as_oldLong ll_newLen // Length of as_newLong ll_delta // Difference of ll_newLen and ll_oldLenLong ll_deltaSum = 0 // Increased sum for ll_deltaString ls_lowerSource // ToLower converted as_source

// Check preconditionIf IsNull(as_source) Or IsNull(as_old) & Or IsNull(as_new) Or IsNull(ab_ignoreCase) Then

SetNull(as_source)Return as_source

End If...

Possible implementation (1/3):

Page 15: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 15

PowerBuilder Strings – Example Code for a case insensitive of_ReplaceAll ()

...ll_oldLen = Len ( as_old ) ll_newLen = Len ( as_new )

If ab_ignoreCase Then // Not Case sensitive as_old = Lower ( as_old ) ls_lowerSource = Lower ( as_source ) ll_delta = ll_newLen - ll_oldLen

ll_pos = Pos ( ls_lowerSource, as_old ) Do While ll_pos > 0 as_source = Replace ( as_source, ll_pos + ll_deltaSum, & ll_oldLen, as_new ) ll_pos = Pos ( ls_lowerSource, as_old, ll_pos + ll_oldLen ) ll_deltaSum += ll_delta LoopElse...

Possible implementation (2/3):

Page 16: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 16

PowerBuilder Strings – Example Code for a case insensitive of_ReplaceAll ()

..Else // Case sensitive ll_pos = Pos ( as_source , as_old )

Do While ll_pos > 0 as_source = Replace ( as_source, ll_pos, ll_oldLen, as_new ) ll_pos = Pos ( as_source, as_old, ll_pos + ll_newLen ) Loop

End If

Return as_source

Possible implementation (3/3):

Page 17: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 17

PowerBuilder Strings – Example Code for a case insensitive of_ReplaceAll ()

PFC’s pfc_n_cst_string.of_global_replace () is a real good example!

But performance and

memory consumption

is not satisfying!

Ideas?

Page 18: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 18

PowerBuilder and DLLs (I)

Q: What is a DLL?

A: DLL = Dynamic Link Library!

Q: What is a Dynamic Link Library?

A: Something like a DLL?!

Page 19: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 19

PowerBuilder and DLLs (II)

Dynamic-Link Library:• Microsoft’s implementation of shared libraries.• Library is organized into sections.• Library can hold code and data (like resources).• Library is loaded when needed during runtime.• Only a single instance will be loaded when used by

multiple applications.• Reference to the DLL’s code is dynamic - not static.• Library usage can be shared – not only the code,

but also the data.

Page 20: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 20

PowerBuilder and C++ - OpenWatcom

• History – Initially 1965 students at the university of Waterloo in

Canada developed a Fortran compiler (WATFOR)– 1985: PC Version of WATFOR-77– 80’s: Rewriting the code in C– 1988: First PC Version Watcom C 6.0

– Code generator supported C and FORTRAN– Portable across multiple platforms ( DOS, Windows,

OS/2, and Windows NT – Popular in the mid-1990s

– Some important games were developed with Watcom C ( DOOM, Descent or Duke Nukem 3D )

– Since 2000 Open Source– License from Sybase allows free commercial use

Page 21: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 21

PowerBuilder and C++ - OpenWatcom Installation

• Download and run setup.– Download the file

open-watcom-c-win32-1.5.exe (59 MB)

from http://www.openwatcom.org/ftp/

or ftp://ftp.openwatcom.org/watcom/

– Execute the file and follow instructions. (Tip: Use a short name for the installationdirectory, like: c:\watcom)

Page 22: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 22

PowerBuilder and C++ OpenWatcom – Program Menu

OpenWatcom provides a set of tools.

Short Demo now!

Page 23: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 23

PowerBuilder and C++ OpenWatcom – Building a DLL

Lab3: PB9 and OpenWatcom Lab:• Filesystem Operations

– Create a new directory– Copy file easydll.cpp to the directory

• Start OpenWatcom IDE – Create a new project (easydll) and save it– Create a new target (easydll.dll)– Add new source (easydll.cpp) to the target – Save project– Make target

Page 24: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 24

PowerBuilder and C++ OpenWatcom – easydll.cpp

// This is the key (copied from pbdll.h)#pragma aux __fortran "*" parm [] modify [ eax ecx edx ];#define PB_EXPORT __export __fortran

// Export Functionsextern "C" { long PB_EXPORT StringReverse ( char *as_input, char *as_output ) ;}// Function Implementationlong PB_EXPORT StringReverse ( char *as_input, char *as_output ) { long l, i;

for (l=0 ; as_input[l]!='\0‚ ; ++l);

for (i=0 ; i<l ; i++) { as_output[l - i - 1] = as_input[i]; } return l;}

Page 25: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 25

PowerBuilder and C++ - Visual C++ 2005 Express Installation• Visit Visual C++ Express Homepage at

msdn.microsoft.com/vstudio/express/visualc• Download

Visual C++ 2005 Express

• Install and run it at least once!

• Download Platform SDK Server 2003 R2

• Install– Tip: You do not need to install the 64-Bit features

• Follow instructions from– msdn.microsoft.com/vstudio/express/visualc/usingpsdk

Page 26: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 26

PowerBuilder and C++ Visual C++ 2005 Exp. – Building a DLL

Lab4: PB9 and Visual C++ Lab:• Filesystem Operations

– Create a new directory – Copy easydll.c, easydll.def and the makefile to

the directory

• Command line– Start „Visual Studio 2005 Command Prompt“– Change current directory – Execute „nmake“

Page 27: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 27

PowerBuilder and C++ Visual C++ 2005 Exp. – easydll.c

__declspec(dllexport) long __stdcall StringReverse ( char *as_input, char *as_output ) { long l, i;

for (l=0 ; as_input[l]!='\0‚ ; ++l);

for (i=0 ; i<l ; i++) { as_output[l - i - 1] = as_input[i]; } return l;}

easydll.def:

LIBRARY "EasyDLL"

EXPORTS StringReverse

Page 28: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 28

PowerBuilder and C++ Back to the of_ReplaceAll ()• Goals

- Avoid to much memory allocation • Minimize usage of Memory space• Minimize Memory actions, like allocation and

freeing of memory- Use an efficient Search Algorithm

• Something like Boyer-Moore algorithm- Support PB9 or PB 10

• ANSI vs. Unicode

• For long strings and a lot of replace operations the best strategy in conjunction with PowerBuilder seems to be a 2-pass strategy.

1. Analyze the string and determine desired memory space

2. Allocate the memory and copy only what you need.

Page 29: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 29

PowerBuilder and C++ Solution for of_ReplaceAll () – (1/2)• C++ Class that supports the 2-pass strategy

- Class uses member variables to store specific information.- Source can be compiled for 8-bit (ANSI) or 16-bit

(Unicode) character usage (TCHAR).

• PowerBuilder nonvisualobject class (Wrapper)- A new instance of the C++-Class will be created for each

PowerBuilder object instance (constructor). - The handle of the C++-Class instance will be stored in an

instance variable of type ’long’.- Local external function calls are declared to invoke the

exported DLL functions.- PowerBuilder code (PBVM) is responsible for the (big)

memory allocation (result string).

Page 30: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 30

PowerBuilder and C++ Solution for of_ReplaceAll () – (2/2)

nv_stringx+ HandleThis

+ constructor ()

+ destructor ()

+ of_replaceall ()

Class cppstringxExternal functions

cppstringx_destroy ()

cppstringx_replaceall ()

cppstringx_getoutput ()

cppstringx_create ()

cppstringx_destroy ()

cppstringx_replaceall ()

cppstringx_getoutput ()

cppstringx_create ()

~destructor

replaceall ()

getoutput ()

constructor

Instance vars

StringX.DLL

Exported functions

Break here for a demonstration of speed!

Page 31: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 31

PowerBuilder and C++ Supporting PB9 and PB10 (Unicode) • The Key to success is to use TCHAR instead of char for

character declarations / definitions.

#include <tchar.h>..// Function Implementationlong PB_EXPORT StringReverse ( TCHAR *as_input, TCHAR *as_output)..TCHAR a;..

• Lab 5. Copy and modify the OpenWatcom EasyDLL Example source code to work with PB10 / PB 10.5. You have to setup a new OpenWatcom Workspace and Target!

• To compile the code to support Unicode you have to set the macro definition ‘_UNICODE ‘ on page 3 of the C++ Compiler Switches.

Page 32: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 32

PowerBuilder and C++ Short info about PBNI

• With PBNI you are able to develop a C++ Class without programming a PowerBuilder object like nv_stringx.

• You can implement a high performance string modifying class or other specialized classes that fit your special needs.

Or wait for others doing this job!

• Demonstration of some PBNI examples.

Page 33: PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst arnd.schmidt@dwoX.com

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt 33

PowerBuilder and C++ - Thank you

Thank you!

dwox.com