Presentation is loading. Please wait.

Presentation is loading. Please wait.

PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst

Similar presentations


Presentation on theme: "PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst"— Presentation transcript:

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

2 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt2 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

3 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt3 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.

4 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt4 Variable ls_test holds the address of the strings first character. Representation in Memory: PowerBuilder Strings – Memory Usage (ANSI) string ls_test = ”PowerBuilder” Heute: PowerBuilder Morgen: 506F7765724275696C64557200 Representation in Memory (Hexadecimal):

5 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt5 PowerBuilder Strings – ASCII Table ASCII Table (00-7F): 0123456789ABCDEF 0 NULSOHSTXEXTEOTENQACKBELBSHTLFVTFFCRSOSI 1 DLEDC1DC2DC3DC4NAKSYNETBCANEMSUBESCFSGSRSUS 2 SP !"#$%&'()*+,-./ 30123456789:;<=>? 4@ABCDEFGHIJKLMNO 5PQRSTUVWXYZ[\]^_ 6`abcdefghijklmno 7pqrstuvwxyz{|}~ DEL

6 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt6 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) Offset01 UTF-16LE5000 UTF-16BE0050

7 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt7 PowerBuilder Strings – UTF16 (UCS-2) Examples of used ranges: RangeNameExamples 0020-007F Basic Latin0-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 ص, ض, ل, ٠, ١, ٢, ٣, ٤,

8 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt8 Variable ls_test holds the address of the strings first character. Representation in Memory: PowerBuilder Strings – Memory Usage (Unicode) string ls_test = ”PowerBuilder” Powerbui lder 50006F007700650072004200750069 006C00640055007200 Representation in Memory (Hexadecimal):

9 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt9 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 () PriorPB10: Functions like LenW() for Unicode support SincePB10: Functions for 1-byte character support like LenA ()

10 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt10 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_test ls_test = & of_ReplaceAll (”ABAABAABAAABA”,”ABA”,’A”) Value of ls_test should be: ”AAAAA”

11 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt11 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 string Return as_source Possible Implementation:

12 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt12 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.

13 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt13 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_test ls_test = & of_ReplaceAll (”ABaabAaBaaABa”,”aBA”,”a”, True) Value of ls_test should be: ”aaaaa”

14 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt14 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_source Long ll_oldLen // Length of as_old Long ll_newLen // Length of as_new Long ll_delta // Difference of ll_newLen and ll_oldLen Long ll_deltaSum = 0 // Increased sum for ll_delta String ls_lowerSource // ToLower converted as_source // Check precondition If 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):

15 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt15 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 Loop Else... Possible implementation (2/3):

16 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt16 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):

17 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt17 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?

18 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt18 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?!

19 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt19 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.

20 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt20 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

21 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt21 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 installation directory, like: c:\watcom)

22 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt22 PowerBuilder and C++ OpenWatcom – Program Menu OpenWatcom provides a set of tools. Short Demo now!

23 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt23 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

24 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt24 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 Functions extern "C" { long PB_EXPORT StringReverse ( char *as_input, char *as_output ) ; } // Function Implementation long 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; }

25 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt25 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

26 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt26 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“

27 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt27 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

28 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt28 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.

29 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt29 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).

30 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt30 PowerBuilder and C++ Solution for of_ReplaceAll () – (2/2) nv_stringx + HandleThis + constructor () + destructor () + of_replaceall () Class cppstringx External 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!

31 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt31 PowerBuilder and C++ Supporting PB9 and PB10 (Unicode) The Key to success is to use TCHAR instead of char for character declarations / definitions. #include.. // Function Implementation long 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.

32 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt32 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.

33 PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt33 PowerBuilder and C++ - Thank you Thank you! dwox.com


Download ppt "PBUGG Meeting, May 2006 - Copyright by Arnd Schmidt1 PowerBuilder and C++ or How to optimize excessive string operations Arnd Schmidt system analyst"

Similar presentations


Ads by Google