« WE ARE THE CHAMPIONS!! | Main| Lotusphere 2007: Background and thoughts on selection process »

Discussion: What technique is faster?

QuickImage   
Category
Bookmark : del.icio.us  Technorati  Digg This  Add To Furl  Add To YahooMyWeb  Add To Reddit  Add To NewsVine 


I was helping out another group with some performance tuning on a large Notes application. There are amy areas we discussed, but one suggestion I gave was interesting. there were multiple NOCACHE DBLookups to the same view, but returning different values. All lookups returned a single document's worth of values, and the view itself contained less than 100 documents; however the overall database contains over 2GB of documents. All lookups are in the same db containing the data. I suggested concatenating the values into a single column, and then retrieve those values, parse them, and use them - the normal stuff we always recommend.

For instance - let's say you have 5 (sets of) values you need to return from a view. 3 are single values, while to are actually small lists of values. You concatenate these values into a single string in a column in the view:

Val1 + "~" + Val2 + "~" + Val3 + "~" + @Implode(Val4; "^") + "~" + @Implode(Val5; "^")

This single column is used in a single lookup in a hidden field called ValueList. Then, you simply use @Word against ValueList in the target fields to parse and retrieve these values as needed. The formulas used to get a particular value in these target fields would be:

Val1 == @Word(ValueList; "~"; 1)
Val2 == @Word(ValueList; "~"; 2)
Val3 == @Word(ValueList; "~"; 3)
Val4 == @Explode(@Word(ValueList; "~"; 4); "^")
Val5 == @Explode(@Word(ValueList; "~"; 5); "^")

Pretty straightforward stuff.

But here's the rub: When the developer implemented this particular recommendation he reported that it was actually slower  than the old method of doing multiple NOCACHE lookups to the view. That surprised me.

I guess I can see that there is a "cost" for parsing the strings - but would that be slower than the lookups? Where is the break-even point? Where does the concatenated/parsing technique actually perform better than the lookup of individual values technique?

I would be curious to see if anyone else has tested things like this, or has any supporting evidence either way. I'd really be interested in hearing some real-world scenarios and results, not just "should work this way", or anectdotal evidence.

What do you folks think? What is your experience?

Rock

**If you've got melted chocolate all over your hands, you're eating it too slowly.

Comments

1 - Hi Rocky,

Saw your post and thought I would try some amateur testing of my own. I found that your suspicions were correct - your technique improves the performance of this functionality greatly. You can check the results at the URL below!

{ Link }

Andrew.

2 - Have you considered, that this may have changed with versions? This breaking up technique is pretty old, so it may be something left over from stone-old versions, which may have changed for example with the rewrite of the @formula engine. And, well, thats only speculation ....

3 - I don't know (didn't test) if it's faster, but how about using the ReCache for the first lookup and then using cache for the subsequent ones. I guess the information will be fresh enough?

4 - I just can't imagine that some String handling should be slower than a database lookup, where probably IO is involved (among others like I would guess identity check of caller, etc.

5 - Try it over a slow dialup connection, or high latency network connection, I doubt the results will be the same...

6 - I tend to do one look-up and then break it out, per your technique. My reasoning was performance -- one look-up has to be better than 10 or whatever -- plus I'd rather troubleshoot one look-up in a web page rather than 10, given how Notes & Domino give the developer NO CLUE where their error might be!

So, I can't offer any illumination, other than I don't notice any particular performance "hit" exploding one string (versus doing look-ups). I'd be surprised if look-ups were quicker, I must confess.

7 - I wonder if the reported SLOWER was due to the calls to @Explode, and not to the calls to @Word.

Also, I think the biggest advantage to this technique is not to be gained in the initial document lookup; but instead to subsequent lookups. The information is maintained in (and therefore pulled from) the cached view's index, rather than actually pulling from the doc itself.

I would be very suprised to discover that subsequent calls anything other than much faster as compared to the initial method.

-Devin.

8 - @Nathan - @Text(@Now;"*") returns a value in the format 85257221:005BC7B4. In multiple successive calls the value after the colon is changing, so I think that's the seconds. I have not been able to subtract two of these values yet to get an elapsed time, and the Notes client is caching my code so every time I make a change I have to close and reopen both the Noes client and Designer. Unfortunately I don't have time to fiddle with this right now.

9 - Charles, there's a formatting technique for time conversion that gives results accurate to 1/100th of a second. It's used for replica ID. I *THINK* it's @Text(timeVal; "*"), but if it's not, you can find it by dissecting the Catalog template.

Internally, time values are more resolute than 1 sec.

Rock... is the view column doing the collapsed string construction, or is it already a field on the doc being looked up?

10 - I attended a session at the 2003 LotusPhere about this very thing. I think it was AD104 "Performance Tuning your Lotus Domino Applications: Lessons Learned from the Field" and either Bob Balaban or Gary Devendorf was the presenter. In that session they showed the time difference between different techniques of doing things. It was a very good session but I can't find my notes on it :- .

Keith

11 - I would start by insisting that they prove that the application is broken when you turn the cache on. Nocache is just for fixing problems, far too many people stick in NoCache as a reflex action everytime they see an @dblookup

12 - You say that he "reported" that it was slower. Makes me wonder: did you actually see the code? If it truly was slower, then the first thing I'd do is verify that the @DbLookup call was coded correctly. I.e., that it is still referring to a view column, and not to a field in the target documents.

13 - I did some tests and subjectively I can say that the parsing technique *looks* like it runs faster, but I can't produce data to back that up. If you can show me how to get less than seconds in formula I'll give you some data. As far as I know the best you can do is whole seconds, though.

14 - Rocky, are you sure your client hadn't forgotten to refresh the design template or something? !!!! I'm amazed that he didn't see an improvement. Like you (and Ben) and most others I guess, I always use the single lookup and parse results technique. And I've always assumed it was faster although I must confess I've never measured it. It wasn't something crazy like the new lookup view you created needed to be built and indexed the first time or something (in other words you have tried it TWICE?)

15 - I wonder if you've tried named caches. Remember, even a cache expires after an extremely short time. The need for "noCache" is NOT universal. Two alternatives are:

a) don't both with it, and let the cache do it's job.

b) try a named cache. @DbLookup("" : "Col1Cache" ; "" ; "Myview"......)


16 - Although the performance results were nearly identical, the network IO is vastly different.

I did two additional tests.

First, I followed Carl's suggestion and went for a higher latency network...first I thought I would use the Internet to introduce latency, but I then figured that it would be to variable for testing purposes...then I remembered that my NIC would allow me to throttle the bandwidth and a I cut the connection down to 10Mbps (and I had to change my switch to support this.)

Low and behold, the expected performance difference appeared. Documents that were generating consistently in the 0.5 sec range, now take either 0.7 secs (one lookup/nine parsed strings) or 5.8 secs (nine independent lookups.)

The more profound effect is with the volume of network traffic generated by each scenario.

My very simple form with only one lookup generated 21 64K payload packets and an equal number of respondent ACKs from the client(as captured by an old copy of Ethereal.) The nine lookup version of the form generated 243 64K payload packets and an equal number of ACKs from the client.

Then I got creative and turned off network encryption and compression on both the client and the server. The first test generated 70 packets, the second over 800 packets.

I am still looking for an R5 client disk to try this again (I found a server disk )

So, use network compression and make as few lookups as possible by exploiting the one lookup/multiple parsed strings technique (also don't rely on anecdotal evidence go for the empirical stuff - and don't forget to reset your NIC and switch back to 1Gbps )

17 - I use the parsed return string method almost exclusively in my development. I couldn't believe that multiple lookups would perform faster, so I decided to test it.

In the Global Declarations I created a variable named 'starttime' of datatype single. In Global Initialize, I set the value of 'starttime' to Timer() (a LS timer function value.) Next in the form's PostOpen, I use a Print timer() - starttime to printout the elasped time of the generation of the form.

With the testing harness in place, I tested a variety of scenarios that touch this topic...cached & nocache & recache single lookups/nine parsed strings as well as cached & nocache & recache nine lookups/no parsing.

To my surprise there was only slight variations (less than 0.08 seconds max on form loads that took a total of ~0.5 seconds) in elapsed times. The server isn't highly tasked and the network I am running across is 1GB duplexed switched.

If I remember correctly, in either 6 or 6.5 there were major changes in Notes' network layer to make Notes less 'chatty'. Could it be that the client is 'packaging' the nine multiple lookups transporting them to the server, the server processing the requests serially, then packaging the nine responses back up and sending them back across the network to the client? If so, then the problem of the network layer slowing things down would be explained. I think I have an R5 disk around somewhere to test this.

Meet Rocky

Rock - February 2010
Rocky Oliver
If you see me at a conference, please stop me and say hi!

Calendar

Search

Categories

Proudly Employed By

Wofkflow Studios

Thawte Notary

Thawte Web of Trust Notary

LOTUS GEEK gear

Social Networking


Add to Technorati Favorites

View Rocky Oliver's profile on LinkedIn

Rocky  Oliver

LotusGeek Blog Roll

Why display a blog roll when Planet Lotus does it so much better?

Dilbert

Buy my book!

Blog Buttons

Atheist - Unitarian - Humanist

Poker Players Alliance