…that is the question. Anyone who has used PPLs in LabVIEW has faced this dilemma at some point. PPLs have a lot of potential benefits. Your application is split up into nicely compiled modules that you can rebuild individually without having to rebuild the whole application. You can dynamically load them at runtime and create plug-in architectures. Rebuilding your top-level executable is a breeze because most of your code is already compiled. Sounds pretty great, huh? Well unfortunately, there’s some down sides too. Managing PPL dependencies is difficult at best and at worst, literally impossible. When PPLs depend on other PPLs you have to start worrying about how the LabVIEW linker finds those dependencies (which, in my experience, is completely inconsistent). The order in which you build the PPLs matters, so you have to be careful to build the low level PPLs before you build the higher level ones that call those PPLs. And all of this is still just dealing with statically linked PPLs. Dynamically loading PPLs introduces a whole new set of problems. Again, you must load the dependency PPLs first, as LabVIEW is not smart enough to load them for you. Also, loading PPLs from disk is extremely slow, so performance can become a real issue.
So where does this leave us? Do the pros outweigh the cons? Or are PPLs a lost cause to be avoided at all costs? The answer is, as is the case for just about every non-trivial question, it depends. Software developers, myself included, typically have a tendency to take a new tool or technology and apply it everywhere, with reckless disregard for that tool’s deficiencies. Imagine for a moment if a carpenter made the same mistake. If a carpenter suddenly decided that the only tool they needed was a screwdriver, they would find themselves not only screwing thing together with it, but also hammering nails and cutting wood with this screwdriver. It seems ridiculous from an outside perspective, but the carpenter is convinced that this screwdriver is the perfect tool, capable of solving all problems…
I think the right question to ask is, “How can we leverage this tool’s benefits, while minimizing the impact of it’s deficiencies?”. In attempting to answer this question, based purely on my personal experience, I came up with the following guidelines:
- Don’t PPL everything. Start out with no PPLs. If you feel you need some PPLs pick a few modules that are highly decoupled from the rest of the application and start there. Be strategic in your application of this tool.
- Prefer statically linked PPLs over dynamically linked ones. This means only using plug-ins where absolutely needed. When you are about to start dynamically loading PPLs, as yourself if you can get away with statically linked PPLs. If so, do that instead.
- Limit the number of layers of PPLs (PPLs that call other PPLs) as much as possible. Any more than 2 or 3 layers becomes very difficult to manage. Ideally your application would have little to no PPLs that depend on other PPLs, but sometimes this is unavoidable. Use with caution.
If you follow these guidelines and, as always, use your best judgement, you’ll avoid many of the pitfalls associated with PPLs, while retaining most of the benefits.