Agent profiling is not new in Domino, but it’s something that gets little press. Because it’s only available for agents, it’s probably also going to become less useful as more and more development is done in XPages. But, working from the premise that the methods in use in LotusScript do the same work on the whole as their Java counterparts, best practices learned from LotusScript are equally applicable to XPages development.
Over the last year there have been countless articles about the performance of NotesViewNavigator compared to NotesViewEntryCollections or NotesDocumentCollections. Innocently (or should that be naively), yesterday I wrote some code that got a NotesViewNavigator using CreateViewNavFromCategory and, to check the navigator had content, called NotesViewNavigator.Count. The code looked like this.
After completing the agent I ran it with profiling turned on. I’m late to the party in that I don’t usually enable this. But my first use has converted me. For the uninitiated, this setting creates a single profile document, updated after each run of the agent. It shows the amount of calls to various methods and the time each took. This was the outcome of the first run.
The agent took 58 seconds, not unacceptable, but the largest hit was from NotesViewNavigator.Count. Called the same number of times as CreateViewNavFromCategory it took about 18 times longer per call. Five minutes later I had made the following minor amendment to the code, to get the first entry from the NotesViewNavigator and check it was not ‘Nothing’ – if there are no entries for the NotesViewNavigator GetFirst still runs.
The second profile below shows the impact this had on the agent performance. 58 seconds had been changed to 733 milliseconds. Not bad for changing two lines of code. Needless to say I will be avoiding NotesViewNavigator.Count in my agent, but also in Server-Side JavaScript and Java, where profiling isn’t available. And I will be using agent profiling much more in the future to enable me to improve my code.
Paul, you are probably aware of this already, but just in case; Phil Riand published the XPages Toolbox project to OpenNTF last year. It contains some very useful methods for profiling server side JS and also custom java code written for XPages:
http://tinyurl.com/XSPToolbox
You can find plenty of examples in the extension library of the patterns that should be adopted in order to make the most of the toolbox’s profiling functionality.
Enjoy (and good catch above!)
Dan
Excellent point, Dan, I’d forgotten about the XPages Toolbox, a great addition to 8.5.2. I’ll definitely get round to that quicker than I got round to agent profiling!
That’s a pretty handy find – I wouldn’t have thought that getting a Count would be significantly more expensive than getting the first entry, but I guess it makes a sort of sense.
Fortunately, there is actually a way to profile your XPages: the XPages Toolbox from http://www.openntf.org/projects/pmt.nsf/ProjectLookup/XPages%20Toolbox . I’ve made great use of the Backend Profiler, which provides the same information as the agent profiler. However, I suspect that it’s the culprit in some recent crashes I’ve had doing development on an 8.5.3 server, so maybe there are some incompatibilities with the latest version, since the toolbox hasn’t been updated in a good while (that I know of).
@ Jesse.. Do you have the specifics of any of the crashes? It is true that the toolbox has not been updated in a while, but if it is causing a crash we will certainly update it.
Thanks.
Dan
@Dan Unfortunately, I didn’t keep specific information about it (and I’m not 100% sure the profiler was the culprit, but it seemed like it), but if it happens again, I’ll try to collect crash logs and a description of the code involved. Would the “Email Project Owners” link on the OpenNTF project’s page be the way to go?
Until I get real specifics, the main notable aspect of the code is that it was going a lot of view traversal and entry processing on databases located on another server.
Speaking from painful experience, is your code recycling each NotesDocument / NotesViewEntry before going onto the next? If not, if it’s a very large view you could have memory issues. I blogged about it just over a year ago. https://www.intec.co.uk/go-green-and-recycle-the-important-information-any-non-java-xpages-dev-needs-to-know/
I’ve also had some server crashes lately when running sessionAsSigner code in SSJS or Java where design elements are signed by more than one user. As soon as I signed the database, the crashes stopped, but I haven’t been able to confirm that sessionAsSigner with signer conflicts was the definite cause, but the NSD logs implied access issues.
Hmm, that .recycle() thing could be related, particularly since I could easily see a profiler changing the characteristics of that kind of thing. I’ve gotten into the habit, for programming convenience, of tossing my product objects into a pool and then recycling them all at the end. When I get a chance, I’ll run some tests.