BP206 - Let's Give Your LotusScript a Tune-Up


Published on

1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • Collection of user comments about bad performing applications
  • BP206 - Let's Give Your LotusScript a Tune-Up

    1. 1. BP 206Lets Give Your LotusScript a Tune-Up Craig Schumann – Senior Developer, Teamstudio Jens-B. Augustiny, CEO, LIGONET GmbH
    2. 2. Who is who? Craig Schumann, Senior Developer at Teamstudio Teamstudio is a producer of Development and Administration tools for IBM Lotus Notes and Domino Jens-B. Augustiny, CEO at LIGONET GmbH Ligonet is a small but active Busines Partner located in Switzerland 2
    3. 3. Agenda What do you mean its slow?  Where do performance problems show up Where the heck is that coming from?  Tips and tools to weed out the slow bits Dont want to go through that again!  Tips for avoiding slowness in the first place 3
    4. 4. What do you mean its slow? 4
    5. 5. Bad performance... what exactly do wemean? The application is bad .... Delivery time vs response time .... Impossible to work with this application This workflow has to be improved in any case!Who has never heard these comments?First and foremost - Make sure you are addressing the right problem. 5
    6. 6. 6
    7. 7. Performance of WHAT? Perceived Performance The user is feeling that the application is not giving the expected output Rather difficult to define, hence rather difficult to analyze Possible fixes:  Better user training - Explain the functionality to the users  Enhance the experience - More information on screen during processing or data entry  Streamline the experience - Change the process flowUser experience can greatly influence how fast an application seems to work. If it is frustrating or takes a long time to enter data, users may report this as bad performance. 7
    8. 8. Real performance ......... or rather the lack of it .... Bottlenecks, that can be verified by timing Almost impossible to anticipate Differences between testing and production environment Any conclusion without actual timing data is pure speculation Timing may influence the result It is important to have empirical data before you start changing anything. Just like with end users, developers have preconceived notions about what the source of the problem might be 8
    9. 9. Example Running the same functionality four times: list all the views of names.nsf 2 parameters are changed: The loop logic and the way that we access the DB properties Which of the four variants is the fastest? Why is your choice the fastest? 9
    10. 10. Core code for the examples 10
    11. 11. Timing resultsFirst runSecond run (caching) 11
    12. 12. Conclusion Results may surprise you Metering should be done in a realistic environment The amount of data and its structure has to be realistic; most testing environments are insufficient Approach of analysis has to be very, very systematic e.g. by narrowing down the points of problem 12
    13. 13. Where the heck is that coming from? So you need actual numbers to justify the work to speed something up..... where are those supposed to come from? 13
    14. 14. Timing with Now Example:BaseTime = Now [.... your code goes here ... ]Print “Time used: “ & Now – BaseTime Advantages Disadvantages Requires changing of code Bad placement falsifies the resultSimple and cheap Insufficient timing resolution 14
    15. 15. High Resolution Timing - GetThreadInfo() Bruce Perry once published an undocumented way to use a high resolution timer http://searchdomino.techtarget.com/tip/1,289483,sid4_gci895240,00.html?FromTaxonomy=%2Fpr%2F283841stc = GetThreadInfo(LSI_THREAD_TICKS) get the starting tick count [....the code you want To Time...]get the final tick countftc = GetThreadInfo(LSI_THREAD_TICKS)get the ticks per secondtps = GetThreadInfo(LSI_THREAD_TICKS_PER_SEC)final tick count minus starting tick count divided by ticks per second yields duration.t = (ftc - stc) / tps 15
    16. 16. High Resolution Timing - GetThreadInfo() Advantages Disadvantages Requires changing of code Bad placement falsifies the result Relatively Simple to implement Makes use of undocumented functions Better resolution than using Now A bit more tricky to use GetThreadInfo() is not guaranteed to work on all versions of Lotus Notes 16
    17. 17. How to communicate the results PRINT to the status bar (client) or the log.nsf (server) Better:  Output to a document  Output to a profile document  Output into an analysis database ..... sorry .... application 17
    18. 18. Example - Make it reusableClass debugTimer Private Start As Variant Private fnName As String Sub New( fn As String ) Set Start = Now fnName = fn End Sub Sub Delete Print fnName & " took " & Now-Start & " seconds to complete." End SubEnd Class 18
    19. 19. Example - Make it reusableSub Initialize() Dim fnTime As New debugTimer( GetThreadInfo(LSI_THREAD_PROC) ) Dim i As Integer While i < 1000 Print i i = i + 1 WendEnd Sub 19
    20. 20. Built in profiling  Introduced in Lotus Notes / Domino 7 ® ® ®  Only for agents and Web Services  Java and LotusScript  Activation in the properties of the Agent or Service  Access to the results by right-clicking on the Agent or Service  There are only results for pure Notes-Objects, no information for your own code 20
    21. 21. Built in profiling - ExampleSub Initialize Dim db As New NotesDatabase( "", "names.nsf" ) i = 0 Dim s As String For i = 0 To UBound(db.views) s =db.Views(i).name Print s NextEnd Sub 21
    22. 22. Built in profiling - Example Run your agent 22
    23. 23. Built in profiling - Example 23
    24. 24. Teamstudio Profiler Timing of functions Timing of code line-by-line Plethora of additional analysis information available Server and Client LotusScript only Application is slowed down a lot You have to pay for it 24
    25. 25. Teamstudio Profiler - Example 25
    26. 26. Dont want to go through that again! 26
    27. 27. Common problems Tooling is a must for existing applications and performance problems, but even better would be not to create the problem to being with! Some of these are just rookie mistakes, others are just careless.So first up.....GetNthDocument! 27
    28. 28. GetNthDocument() Running through a Doc-Collection with GetNThDocument(n) is a lot slower than getting the first doc with GetFirstDocument and then going through the collection by GetNextDocument (doc) Much has been said about this ... mostly all can be read online http://bobzblog.com/tuxedoguy.nsf/dx/getnth-revisited-helpful-function-or-spawn-of- the-devil http://www.lotusgeek.com/LotusGeek/LotusGeekBlog.nsf/d6plinks/ROLR-7HHPER Be familiar with the limitations of the API you are using. There are no bad functions, but not every function is appropriate for all situations. 28
    29. 29. Check your loop logicfound=FalseDo Until (selected_doc Is Nothing) If (selected_doc.Form(0)="fa_Term") Then found=True End If Set selected_doc=term_collection.GetNextDocument(selected_doc)LoopSet selected_doc=term_collection.GetFirstDocument()If Not(found=True) Then MessageBox NO_TERM_DOCUMENTS_SELECTED_TO_DELETE, 16,DELETE_ERROR Exit SubEnd If 29
    30. 30. and fix your bugs....found=FalseDo Until (selected_doc Is Nothing) If (selected_doc.Form(0)="fa_Term") Then found=True loop should short circuit here!! End If Set selected_doc=term_collection.GetNextDocument(selected_doc)LoopSet selected_doc=term_collection.GetFirstDocument()If Not(found=True) Then MessageBox NO_TERM_DOCUMENTS_SELECTED_TO_DELETE, 16,DELETE_ERROR Exit SubEnd If 30
    31. 31. Fix your bugs - Code Rot Fact - Code changes over time. Requirements change, better ways of doing things are discovered. Make sure your code changes are complete before moving on other wise performance suffers Sub Queryopen(...) Dim session As New NotesSession Set db = session.currentdatabase Set view = db.getview("People") Set ProfileDoc = db.getprofiledocument("PickerView") ProfileDoc.Pview = "People" End Sub The variable view is never used anywhere on the form. NotesDatabase.GetView() is an expensive call to make on a QueryOpen. Especially if it is never used. 31
    32. 32. Careful with nested IFs  Unlike languages like C and Java LotusScript always evaluates all conditions in an if statement. x = 1 If x = 0 And checkresult( res ) = 0 Then do some stuff End IfCheckresult() will always be called. Performance problems can easily be masked in seemingly simple statements like this. 32
    33. 33. Careful with nested IFs – The Fix  The correct statement is the following: x = 1 If x = 0 Then If checkresult( res ) Then do some stuff End If End IfCheckresult() will only be called when the first statement is true. 33
    34. 34. Variables – Variant is slower  Besides being breeding grounds for bugs the Variant data type is inherently slower than typed variables.  LotusScript will have to figure out the type at some point and provide a conversion to the correct type.  Dont be lazy! Use Option Declare 34
    35. 35. Loops – Some are faster than othersForall through arrays much faster than For ..... NextFor ... Next is faster than Do ..... Loop or While ..... Wend 35
    36. 36. Left overs....  Access to selected documents is faster by accessing them through a view instead of a document collection  Access to Notes object through a temporary variable is faster than accessing them every time through the property of another Notes object 36
    37. 37. Summary There are technical and non-technical reasons for performance issues If the issue is technical, any statement without metering is pure speculation There are no two identical cases Systematic top down analysis is very, very important Sometimes the redesign of the application is the best way to remove the issues There are some best practices 37
    38. 38. Thank you!Questions?Maybe there are even answers ..... :-)Craig Schumann - Teamstudiocraig_schuman@teamstudio.comwww.teamstudio.comJens-B. Augustiny - LIGONET GmbHaugustiny.j@ligonet.chwww.ligonet.ch 38
    39. 39. Legal Disclaimer© IBM Corporation 2009. All Rights Reserved.The information contained in this publication is provided for informational purposes only. While efforts were made to verify the completeness and accuracy of the information contained in this publication, it is provided AS ISwithout warranty of any kind, express or implied. In addition, this information is based on IBM’s current product plans and strategy, which are subject to change by IBM without notice. IBM shall not be responsible for anydamages arising out of the use of, or otherwise related to, this publication or any other materials. Nothing contained in this publication is intended to, nor shall have the effect of, creating any warranties or representationsfrom IBM or its suppliers or licensors, or altering the terms and conditions of the applicable license agreement governing the use of IBM software.References in this presentation to IBM products, programs, or services do not imply that they will be available in all countries in which IBM operates. Product release dates and/or capabilities referenced in this presentationmay change at any time at IBM’s sole discretion based on market opportunities or other factors, and are not intended to be a commitment to future product or feature availability in any way. Nothing contained in thesematerials is intended to, nor shall have the effect of, stating or implying that any activities undertaken by you will result in any specific sales, revenue growth or other results.Performance is based on measurements and projections using standard IBM benchmarks in a controlled environment. The actual throughput or performance that any user will experience will vary depending upon manyfactors, including considerations such as the amount of multiprogramming in the users job stream, the I/O configuration, the storage configuration, and the workload processed. Therefore, no assurance can be given thatan individual user will achieve results similar to those stated here.IBM, the IBM logo, Lotus, Lotus Notes, Notes, Domino, Quickr, Sametime, WebSphere, UC2, PartnerWorld and Lotusphere are trademarks of International Business Machines Corporation in the United States, othercountries, or both. Unyte is a trademark of WebDialogs, Inc., in the United States, other countries, or both.Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.Microsoft and Windows are trademarks of Microsoft Corporation in the United States, other countries, or both.Intel, Intel Centrino, Celeron, Intel Xeon, Intel SpeedStep, Itanium, and Pentium are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States and other countries.UNIX is a registered trademark of The Open Group in the United States and other countries.Linux is a registered trademark of Linus Torvalds in the United States, other countries, or both.Other company, product, or service names may be trademarks or service marks of others. 39