dev-21: optimising your abl for performance making your code go faster gus björklund wizard,...
TRANSCRIPT
DEV-21: Optimising Your ABL For Performance
Making your code go faster
Gus BjörklundWizard, Progress Software Corporation
© 2007 Progress Software Corporation2 DEV-21:Optimizing Your ABL for Performance
"More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity.”
W.A. Wulf
© 2007 Progress Software Corporation3 DEV-21:Optimizing Your ABL for Performance
“The First Rule of Program Optimisation: Don't do it.
The Second Rule of Program Optimisation (for experts only!): Don't do it yet.”
Michael A. Jackson
© 2007 Progress Software Corporation4 DEV-21:Optimizing Your ABL for Performance
Things
Why optimise When to optimise What to optimise How to optimise
© 2007 Progress Software Corporation5 DEV-21:Optimizing Your ABL for Performance
Why optimise
© 2007 Progress Software Corporation6 DEV-21:Optimizing Your ABL for Performance
Why (not) optimise
Optimising is work Processors get faster and faster Databases get faster and faster Disks get faster and faster (and bigger) Memory gets faster and faster (and bigger)
Why spend time optimising when we don’t need to,and you just warned me not to do it ??
© 2007 Progress Software Corporation7 DEV-21:Optimizing Your ABL for Performance
Why optimise
Performance is never good enough Can’t ask customer to buy a new machine Faster machines won’t solve every problem No machine bigger than the biggest Smaller machines cost less than big ones You can put more users on a machine Better performance improves customer
satisfaction
But: Don’t do work that is not needed!
© 2007 Progress Software Corporation8 DEV-21:Optimizing Your ABL for Performance
When to optimise
© 2007 Progress Software Corporation9 DEV-21:Optimizing Your ABL for Performance
When to optimise
After you have• spent enough time thinking
• chosen the right algorithms
• working code
• measured performance of your application
• determined you have a problem
© 2007 Progress Software Corporation10 DEV-21:Optimizing Your ABL for Performance
What to optimise
© 2007 Progress Software Corporation11 DEV-21:Optimizing Your ABL for Performance
The Pareto principle
80 % of the consequences stem from 20 % of the causes
© 2007 Progress Software Corporation12 DEV-21:Optimizing Your ABL for Performance
"We should forget about small efficiencies, say about 97% of the time: premature optimisation is the root of all evil. Yet we should not pass up our opportunities in that critical 3%.”
D.E. Knuth
You have to find that 3 % !
© 2007 Progress Software Corporation13 DEV-21:Optimizing Your ABL for Performance
Finding the 3 %
© 2007 Progress Software Corporation14 DEV-21:Optimizing Your ABL for Performance
Measure
ALWAYS measure effects Measure more than once
• different data gives different results
Sometimes the “improvements” you make won’t be worthwhile or will make things worse.• Take those out
You need a performance regression test suite
© 2007 Progress Software Corporation15 DEV-21:Optimizing Your ABL for Performance
“Measure twice, cut once”carpenter’s adage
© 2007 Progress Software Corporation16 DEV-21:Optimizing Your ABL for Performance
Measuring performance
4GL profiler a watch the time, timex commands instrument your code log files
© 2007 Progress Software Corporation17 DEV-21:Optimizing Your ABL for Performance
The 4GL profiler
See $DLC/src/samples/profiler/readme.doc Get the “profiler control tool” from PSDN No code changes needed Tells you:
• Time spent in various parts of your program• Call hiearchy• Number of times each part is executed
Learn how to use it! Profile your application
© 2007 Progress Software Corporation18 DEV-21:Optimizing Your ABL for Performance
Measuring with etime()
def var startTime as int64 no-undo.def var endTime as int64 no-undo.
startTime = etime(false). for each customer: end.endTime = etime(false).
display endTime - startTime.
© 2007 Progress Software Corporation19 DEV-21:Optimizing Your ABL for Performance
Measuring with datetime
def var startTime as datetime no-undo.def var endTime as datetime no-undo.def var elapsedTime as int64 no-undo.
startTime = now. for each customer: end.endTime = now.
elapsedTime = interval (endTime, startTime, "milliseconds").display elapsedTime.
© 2007 Progress Software Corporation20 DEV-21:Optimizing Your ABL for Performance
How to optimise
© 2007 Progress Software Corporation21 DEV-21:Optimizing Your ABL for Performance
How to optimise
Start with working code and tests You DON’T know where the problem is The problem will move Try one thing at a time Remove changes that didn’t work Know when to stop
© 2007 Progress Software Corporation22 DEV-21:Optimizing Your ABL for Performance
How to optimise:various tips and techniquesin no particular order
© 2007 Progress Software Corporation23 DEV-21:Optimizing Your ABL for Performance
Comments and white space do notimpede performance.
What is the most important thing?
© 2007 Progress Software Corporation24 DEV-21:Optimizing Your ABL for Performance
Which algorithm is faster?
def var n as integer no-undo.def var sum as integer no-undo.
sum = 0. do n = 1 to 1000: sum = sum + n. end.
n = 1000. sum = (n * (n + 1)) / 2.
© 2007 Progress Software Corporation25 DEV-21:Optimizing Your ABL for Performance
Avoid Unnecessary XML
Parsing XML uses many cpu cycles XML is a memory hog XML documents are often big
© 2007 Progress Software Corporation26 DEV-21:Optimizing Your ABL for Performance
Clean your room
Delete dynamic objects and widgets you don’t need anymore• dynamic object tracker
• session:system:first-procedure, etc
Use widget pools Get rid of temp tables you don’t need Get rid of objects you don’t need
© 2007 Progress Software Corporation27 DEV-21:Optimizing Your ABL for Performance
Temp tables
Pass BY-REFERENCE or pass handle Raise -Bt
• -Bt sets number of temp-table buffers• default is low
Use EMPTY TEMP-TABLE when possible, instead of FOR EACH tt: DELETE tt. END.
Use MIN-SCHEMA-MARSHAL or NO-SCHEMA-MARSHAL attribute when passing TTs to/from app servers
© 2007 Progress Software Corporation28 DEV-21:Optimizing Your ABL for Performance
Use NO-UNDO Variables
def var foo as integer no-undo.def var bar as character no-undo.
(would have been nice if this hadbeen the default behaviour,but is not)
© 2007 Progress Software Corporation29 DEV-21:Optimizing Your ABL for Performance
Group assigns
assign i = 3 j = 5 c = “abcdef” .
i = 3. j = 5. c = “abcdef”.
NoYes
© 2007 Progress Software Corporation30 DEV-21:Optimizing Your ABL for Performance
BUFFER-COPY beats ASSIGN
BUFFER-COPY source TO target
optionsEXCEPT list
USING list
NO-LOBS
© 2007 Progress Software Corporation31 DEV-21:Optimizing Your ABL for Performance
Avoid redundant code
Do calculations once and reuse result wherever possible
j = someFunction ().do i = 1 to 10: stuffend. do i = 1 to 10:
stuff j = someFunction ().end.
© 2007 Progress Software Corporation32 DEV-21:Optimizing Your ABL for Performance
Redundant code
do n = 1 to someFunctionOrOther(): … stuff.end.
i = someFunctionOrOther(). do n = 1 to i: … stuff. end.
© 2007 Progress Software Corporation33 DEV-21:Optimizing Your ABL for Performance
Eliminate unnecessary code
Code that isn’t there executes in zero time
“If we wish to count lines of code, we should not regard them as lines produced but as lines spent.”
Edsger Dijkstra
“Inside every large program there is a small program trying to get out.”
Sir Tony Hoare
© 2007 Progress Software Corporation34 DEV-21:Optimizing Your ABL for Performance
Loop hoisting
do I = 1 to 50: if expression1 then run bar(). else do: if expression2 then do: run foobar(). end. else run foo(). end.end.
if expression1 then do I = 1 to 50: run bar(). end.else do: if expression2 then do I = 1 to 50: run foobar(). end. else do I = 1 to 50: run foo(). end.end.
© 2007 Progress Software Corporation35 DEV-21:Optimizing Your ABL for Performance
DO instead of REPEAT
sum = 0. repeat n = 1 to 10000: sum = sum + n. end.
sum = 0. do n = 1 to 10000: sum = sum + n. end.
63 milliseconds 57 milliseconds
© 2007 Progress Software Corporation36 DEV-21:Optimizing Your ABL for Performance
Minimise block nesting
IF expression THEN statement.
instead of
IF expression THEN DO: statement. END.
© 2007 Progress Software Corporation37 DEV-21:Optimizing Your ABL for Performance
Use CASE instead of nested IF
CASE status: WHEN 1 THEN DO: END.
WHEN 2 THEN DO: END.
WHEN 3 THEN DO: END.
OTHERWISE DO: END.END.
© 2007 Progress Software Corporation38 DEV-21:Optimizing Your ABL for Performance
Increase sort buffers
Set -TB to 31 (buffer size) Set -TM to 24 (number of merge buffers)
© 2007 Progress Software Corporation39 DEV-21:Optimizing Your ABL for Performance
Avoid deep object hierarchies
constructors have to be run for each class you inherit from
destructors have to be run for each class you inherit from
CLASS A:END CLASS.
CLASS B INHERITS A:END CLASS.
CLASS C INHERITS B:END CLASS.
CLASS D INHERITS C:END CLASS.
new (D) runs 4 constructors
© 2007 Progress Software Corporation40 DEV-21:Optimizing Your ABL for Performance
Minimise creation of subprocesses
Creating a process is one of the most expensive system calls
© 2007 Progress Software Corporation41 DEV-21:Optimizing Your ABL for Performance
Duff’s Device
switch (count % 8) { case 0: do { *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; } while ((count -= 8) > 0); }
© 2007 Progress Software Corporation42 DEV-21:Optimizing Your ABL for Performance
Use sequences
Does not require locking records Can cause gaps in numbering though You can use UUID’s for unique keys instead
of sequences
10.1B has 64-bit sequences
© 2007 Progress Software Corporation43 DEV-21:Optimizing Your ABL for Performance
Queries
Avoid unindexed CAN-FIND Use word indexes for status indicators Avoid queries on boolean values Careful with OR predicates in WHERE
clauses Add more indexes Get rid of unused indexes COMPILE XREF Exchange sessions on indexing
© 2007 Progress Software Corporation44 DEV-21:Optimizing Your ABL for Performance
HIDE screen data while calculating
See recent PEG thread on LockWindowUpdate• search for “window update” to find it.
© 2007 Progress Software Corporation45 DEV-21:Optimizing Your ABL for Performance
Avoid CONNECT
CONNECT is somewhat slow
CONNECT at runtime requires r/w access to database files (insecure)
© 2007 Progress Software Corporation46 DEV-21:Optimizing Your ABL for Performance
Propath
use -q option• propath search is done only once
Keep propath as short as possible• The more entries in propath the longer the
searches can take
Order entries by frequency of use• Put most frequently used in front
© 2007 Progress Software Corporation47 DEV-21:Optimizing Your ABL for Performance
Shared Procedure libraries
Use when same code run by multiple sessions ON SAME MACHINE
Whole library is mapped in one call Saves memory due to single copy
• Memory can then be used to improve performance
– Bigger database buffer pool– More users– Can reduce paging (if you are)
Marginally faster due to opening fewer .r files
© 2007 Progress Software Corporation48 DEV-21:Optimizing Your ABL for Performance
Cost of RUN
type relative time (ymmv)
internal procedure 1 ( ~ 5 microseconds)
persistent procedure 1.5
external procedure 2.3
web service invocation ~ 1,000 to 15,000
web service invocation time is highly variable and depends on:processor speednetwork speednumber of hopsdistancetime of dayday of weekload on serverwhich wsdl and soap options are used
© 2007 Progress Software Corporation49 DEV-21:Optimizing Your ABL for Performance
More stuff
Compile with -min-size option Use shared memory database connections
when possible (avoid networking) Single user mode usually isn’t fastest
• compared to multi-user with 1 user
© 2007 Progress Software Corporation50 DEV-21:Optimizing Your ABL for Performance
Measure
Sometimes the changes you make won’t be worthwhile
ALWAYS measure effects Measure more than once
• with different data
Batch jobs should always write to a log file• Watch for changes in duration over time
© 2007 Progress Software Corporation51 DEV-21:Optimizing Your ABL for Performance
Code Reviews
You don’t know everything You might have overlooked something There might be a better way
© 2007 Progress Software Corporation52 DEV-21:Optimizing Your ABL for Performance
Other things to do
© 2007 Progress Software Corporation53 DEV-21:Optimizing Your ABL for Performance
Other things to do
Add more memory Simplify your application Tune your database
• See “OpenEdge® RDBMS Performance Tuning Made Simple” on PSDN or PEG
DataServers• “Building High Performance Applications with the
Progress Oracle DataServer” on PSDN
• “DataServer Best Practices” on PSDN
© 2007 Progress Software Corporation54 DEV-21:Optimizing Your ABL for Performance
Where to learn more
The PEG (www.peg.com) PSDN (psdn.progress.com) 4GL Programming Handbook Past Exchange sessions Progress course on ABL performance
© 2007 Progress Software Corporation55 DEV-21:Optimizing Your ABL for Performance
Questions