Thursday, July 10, 2008

The Importance of Style in LabVIEW Programming

Earlier this week, my wife, son, and I visited the teaching greenhouse at UConn, to see a specimen of a Sumatran Corpse Flower (amorphophallus titanum) in bloom. Relatively rare in captivity, these plants are the rock stars of the horticultural world, producing a single flower six feet tall which lasts less than a day. They also smell like a putrid rotting cadaver, adding to the fascination. What does this all have to do with LabVIEW, you ask? Read on and you'll see.

Over the years, much has been written and discussed regarding the importance of good programming style. Several years ago, the (now defunct) LTR newsletter had an excellent article entitled "Rules to Wire By"; it's still relevant, and you can read it here. An authoritative book on the subject, The LabVIEW Style Guide, was published last year by my former boss, Peter Blume. It's an exhaustive compilation of rules, recommendations, examples, and illustrations of good and bad LabVIEW style. It covers a lot of ground and can serve as a great reference for those seeking to perfect this aspect of their LabVIEW programming skills. This book grew out of a presentation Peter gave at NIWeek 2002, which you can download here. The terrific books by Gary Johnson, Jeff Travis, Jim Kring, Jon Conway, and others, further strengthen the LabVIEW references available to experienced programmers and neophytes alike. With these and all of the myriad other resources available, you'd think that there would be no excuse for some of the poor code which we've all seen in our careers.

The trouble is, style is not enough.

Recently, I witnessed a project that went from bad to worse. The original programmer produced an application that didn't look all that good, and functioned poorly. The project was re-assigned to another engineer in the company, a CLA at that. She refactored the code according to the best style standards available, but didn't pay enough attention to the underlying program's structure, and as a result its performance didn't meet the customer's requirements. Re-assigned yet again, to yet another CLA, nothing really improved. The code got prettier and prettier with each iteration, but no one addressed the fundamental design issues which prevented the program from meeting its goals.

LabVIEW is an easy language to learn and easy to start programming. It's also the easiest language to program poorly, and unlike text-based languages, your code will still run -- maybe even run fairly well. LabVIEW seems to cast a spell over even experienced programmers in other languages who seem to forget everything they used to know. People jump right into coding without giving any thought to program design. The old standard concepts of structured programming, hierarchical organization, abstraction, modularity, of loose coupling and tight cohesion... gone in a flash. By paying attention to style, your poorly-written code can be made to look marvelous. Personally, I'd much rather deal with a well structured application that happens to have crooked wires and overlapping block diagram objects, than a lovely piece of code that's written without attention to the disciplines mentioned above.

A LabVIEW program that's created using correct style but without appropriate design is like a Corpse Flower: it's beautiful and looks very impressive, but it still stinks.

Monday, July 7, 2008

Insidious Memory Leaks, Part 1

Memory leaks are the bane of any software application that must run continuously for long periods of time. The common causes -- building arrays or concatenating strings within loops -- are relatively easy to spot for most developers. However, leaks can sometimes creep into applications in seemingly harmless ways. Consider the following code snippet, developed by a local integrator, that was extracted from an instrument polling loop that runs in parallel to a main application.It looked innocuous enough to me... Sure, why not use a notifier to stop the loop when the main application is stopped? It seemed to run without problems under Windows. However, when it was downloaded to a PXI-RT target, it leaked like a screen door on a submarine. The fix was simple enough: put the Obtain Notifier outside of the loop and pass in the refnum through a tunnel. You would think that Obtain Notifier would simply return a pointer to the existing notifier, but apparently things work differently enough in RT to cause headaches. I haven't tried it yet, but I bet the same (mis)behavior is evident when obtaining refnums from other synchronization tools.

The moral of the story is a simple one you see over and over again: if a code element doesn't need to be in a loop, then don't put it there. Duh.