« Let's put it to a vote | Main| Delegate math »

NULL and void

Category domino performance
By now, we all know (hopefully) not to use GetNthDocument to loop through document collections, but here's something that often gets overlooked: don't use NULL in formula to determine if a field is blank. NULL doesn't exist.

In LotusScript, the keyword Null basically means "unknown" or "invalid". For example, ArrayGetIndex returns Null if the search value does not exist in the source array. You can manually assign Null to a variable - but only if it's a Variant - and then use IsNull to see if it's still Null, but I'd advise against that, since the only way a value can be Null is if you specifically tell it to be or assign it to an expression that returns Null. IsNull(""), for example, returns False.

In formula, although @IsNull does exist, NULL simply has no meaning. It's not a reserved keyword, so much like extended syntax in LotusScript, it doesn't know what it means, so it assumes you're referring to a field. Since there is no field (again, hopefully) named NULL, NULL returns "". So technically you get the same result, just more slowly.

This reminds me of trying to navigate one of those voice-activated menus when I try to call the customer service department of an ISP, utility company, insurance agent, etc. After trying unsuccessfully to determine how to contact an actual human, I'll just say "human". More often than not, the response is: "I'm sorry, I didn't understand you. I'll transfer you to a representative." The result was precisely what I wanted, it just took longer than it would have if I'd known to just push 0 at the start of the call.



In other words, the following formulae all return the same Boolean value:

Subject = NULL
Subject = ""
@IsNull(Subject)
@Length(Subject) = 0

The last is the most efficient, but arguably the least readable. I'd still recommend it, though, for use in column formulae for potentially large views and view selection for any view in a potentially large database. For performance purposes, hide-whens on forms/subforms should be kept to a minimum anyway, but the more you have the more noticeable it becomes if you're asking if some field value = NULL in each: Notes has to check each time whether a field named NULL exists, find out that it doesn't, evaluate NULL to "", and then do a string comparison between "" and the field you've specified. With @Length(FieldName) = 0, it's just checking the length of the field value, then comparing one number to another. Again, slightly less readable, but faster every time.

(cross-posted at BleedYellow)

Comments

Gravatar Image1 - This blog entry has the Andre seal of approval. I haven't actually tested the timing, but what you say makes sense.

Gravatar Image2 - I'm not arguing with you or Andre, I want to make sure I understand what's going on. Emoticon

When you use @Length(fieldname), doesn't the formula engine have to check to see if fieldname exists before it does the @Length of it? Or is it not the field name lookup that's the expensive operation, it's the substitution of an empty string that takes a few ticks?

Gravatar Image3 - @Charles - you're right, @Length does have to evaluate the length of that field's value; there's no way around that calculation. It's the additional evaluations that theoretically get expensive. So here's how it breaks down:

@Length(FieldName) = 0
- Does field FieldName exist?
- If so, what's the length of its value?
- Is that length equal to 0? (numeric comparison)

FieldName = ""
- Does field FieldName exist?
- If so, what's its value?
- Is that value equal to ""? (string comparison)

FieldName = NULL
- Does field FieldName exist?
- If so, what's its value?
- Does field NULL exist?
- It doesn't, so NULL equals ""
- Is the value of FieldName equal to ""? (string comparison)

So the first is minutely faster than the second, but should be even faster than the third. The difference each time should be negligible, but put that same evaluation set in 87 different hide-when formulae on the same form (or worse, a column formula indexed against tens of thousands of documents in a view), and it's likely to add up.

Gravatar Image4 - I tend to use @IsAvailable in these situations. I haven't done any speed testing but I would assume this to be quicker because all it does is the first step - does the field exist?

It is also very descriptive if I am really just trying to check for the presence of the field, and don't care about the field's contents

Gravatar Image5 - @Michelle - you're right: if you just want to be sure the field exists, @IsAvailable is efficient. The places I've seen NULL used, however, are typically hide-whens where the developer is trying to hide a whole section of a form if a field related to that section isn't populated. For example, an "Advanced Options" checkbox that, if checked, displays an additional set of fields.

In this scenario, because the checkbox field is defined on the form, @IsAvailable will always return True regardless of the field's value, so the additional fields would always display (or always hide, depending on the role @Available plays in the hide-when formula).

Post A Comment

:-D:-o:-p:-x:-(:-):-\:angry::cool::cry::emb::grin::huh::laugh::lips::rolleyes:;-)

Contact Me

Hire Me

Elsewhere

What the Quote?

"Squish, squish, blueberry juice"

Tim Tripcony

"I'd rather be bitten by another copperhead than go through another finals week."

Matt DeBerard

"Blow the road's nose."

Laura Tripcony

"I'm pretty sure that the Great Leader is some sort of twisted ass freak."

Brent Bowers

"Let me just ask you this so I can go cause more wanton destruction."

Alex Belt

Apparel

Lotus Rocks

I write the code that makes the young girls cry

Current Terror Alert Level

Assorted Linkage

ClustrMap