Jump to content

Data Access Best Practices?


cycleguy

Recommended Posts

Shift registers in most cases. If only very few states access the data, AEs/FGVs.

Felix

Similar to what I teach my people. If the SR's are well designed clusters (only related data is grouped) then you can quickly spot which SR to move into the AE's by clicking through the states looking for a SR that only gets touched in a handful of places.

Ben

Link to comment

I normally use a single SR (cluster) per module (SM) and if by design or if data gets complex (I.e. it should be encapsulated) I usually use classes within the cluster (to manage the data easily).

Modules can call other modules, like the posts above.

Link to comment

Another option is a current value table (also known as a currnet value repository) using variant attributes (discussed a little here). We have an internal reuse library that wraps the get/set methods (think polymorphic) and includes other functions like write-to/read-from file, search for tags using wildcards, probes, etc.

post-181-0-46509900-1297173827_thumb.gif

There's also a CVT example from NI here - it's strictly-typed, but it might give you some ideas.

  • Like 1
Link to comment

I usually use shift registers. Normally 2. One for the control/status etc. And one for data. Local variables get very messy very quickly.

Is it okay if I disagree with you? :P

Dragging shift register wires from one side of a diagram to the other, having to hop over other code that may be in an event case (for example), now THAT gets messy. For pure mess-reduction, local variables are the best way to go.

But obviously it's not all just about mess-reduction, which is why local variables are generally used sparingly if at all.

Link to comment

Is it okay if I disagree with you? :P

... For pure mess-reduction, local variables are the best way to go.

But obviously it's not all just about mess-reduction, which is why local variables are generally used sparingly if at all.

Sure, as long as I don't have to support the code.

Does your definition of "Pure mess-reduction" completely ignore performance and ease of support?

If so I agree whole-heartedly.

:P :P

Ben

Link to comment

Local variable should not be used to 'store' data. This is really bad practice.

And if you really want to be anal they should only really be used to update a Control's display.

If you use a template and lay it out, you should never have an issue with space. Like Shaun I sometimes use a couple of SR registers (for example, a private dynamic event refnum so I don't have to type it and keep updating it) but I always leave enough space so that I don't have to move code. Also since 8.6 you can set the tunnels to wire through automatically, which is a really cool feature.

Link to comment

Is it okay if I disagree with you? :P

Dragging shift register wires from one side of a diagram to the other, having to hop over other code that may be in an event case (for example), now THAT gets messy. For pure mess-reduction, local variables are the best way to go.

But obviously it's not all just about mess-reduction, which is why local variables are generally used sparingly if at all.

Linked tunnels mean you don't have to keep wiring them through. But even without them, I would never have more than 10 cases (yes. I'm looking at you JGCode...lol) so it wouldn't be a big deal. I also don't generally hop over code. I wire through sub-vis as I like to only have only sub-vis in each case frame rather than raw code - much cleaner and gives you the opportunity to make them subroutines. Locals (and globals for that matter) I try to avoid since you cannot sequence them with error wires. If it doesn't matter about UI updating affecting performance, I prefer to use a property node (because of the error terminal). But that's nothing to do with state-machines :P

But then, I'm me. And that's a bad thing biggrin.gif

  • Like 1
Link to comment

Sure, as long as I don't have to support the code.

Does your definition of "Pure mess-reduction" completely ignore performance and ease of support?

If so I agree whole-heartedly.

:P :P

Ben

I was wearing my Devil's Advocate hat when I wrote that. :)

Shaun was talking about messiness, and I had just done some wiring on an event case that would have looked a lot neater if I would have used a couple local variables. But I know that's a no-no. :nono::P

Link to comment

Linked tunnels mean you don't have to keep wiring them through. But even without them, I would never have more than 10 cases (yes. I'm looking at you JGCode...lol) so it wouldn't be a big deal. I also don't generally hop over code. I wire through sub-vis as I like to only have only sub-vis in each case frame rather than raw code - much cleaner and gives you the opportunity to make them subroutines. Locals (and globals for that matter) I try to avoid since you cannot sequence them with error wires. If it doesn't matter about UI updating affecting performance, I prefer to use a property node (because of the error terminal). But that's nothing to do with state-machines :P

But then, I'm me. And that's a bad thing biggrin.gif

I agree with most of what you posted and tend toward keeping the number of cases low (in state machines) but the number is not the critical factor but rather the State Transition Diagram (STD) that is realized by the code. I suspect someone out there knows the theory behind it but the point at which STD get confusing is when it can no longer be drawn in a single plane, i.e. the transition lines have to cross over others. That is what I concider my "stop and re-write" point durring the design process. But before I let the diagrams get to that point I will start creating sub-STDs with a cohesive function and replacing the calling STD's code with the new "state". These are generally characterized by "single line in... single line out" structure in my STDs.

But that is off-topic now so I should stop.

Cat,

Yup. That is what the double smiley-back at you was all about.

:beer_mug:

Ben

Link to comment

I agree with most of what you posted and tend toward keeping the number of cases low (in state machines) but the number is not the critical factor but rather the State Transition Diagram (STD) that is realized by the code. I suspect someone out there knows the theory behind it but the point at which STD get confusing is when it can no longer be drawn in a single plane, i.e. the transition lines have to cross over others. That is what I concider my "stop and re-write" point durring the design process. But before I let the diagrams get to that point I will start creating sub-STDs with a cohesive function and replacing the calling STD's code with the new "state". These are generally characterized by "single line in... single line out" structure in my STDs.

But that is off-topic now so I should stop.

Ben

Not really off topic. The OP did ask about state-machines and what other people use.

I'm with you on the sexually transmitted disease STD. I was generally referring to those that save a file using 20 case frames instead of just having "save" (because a certain tool makes it easy to do wink.gif). I've never found a need for more than 10 in control systems (well, I think there was a 12 once, but I eventually got it to less than 10). Simply because I do as you. The state-machine goes across the diagram and INTO the diagram (I think that's what you are saying).

OK some state transitions aren't "kosha" (to get back the next level it might rattle through a few basically bypassing and doing a doing a NOP). But thats data-flow for ya. I actually find Labview pretty good for realising multi-planar machines where I equate each plane as a level in the VI hierarchy - Seems intuitive to me. Sure a few implementation problems. But much easier to debug a single branch in isolation than a fat, wide one with 100 states.

Link to comment

Have you never responded to more than 10 events on FP and had to wire data through each case?

An event structure isn't a state machine :) Oops I forgot. You ab use it as one by firing off ValSig biggrin.gif (Been known to do that myself on occasions....lol).

But Linked tunnels work on it too

  • Like 1
Link to comment

An event structure isn't a state machine

QFT. :star:

Maintaining data between loop iterations and carrying it through the case structure doesn't make the loop a state machine. It just makes it a loop with data you want to persist between iterations. It *has* state, but it's not necessarily a state machine.

The OP mentioned a "simple state machine," which I interpret as the enum-into-a-case-structure kind. For that the shift register is the best way to go.

Link to comment

An event structure isn't a state machine :)

Really? Then what do you call something that looks like this?

post-10325-0-19185500-1297331128_thumb.p

Queued State Machine, Queued Message Handler, QSM with event structure, etc...

I know what NI call it and what others have called if for years so I am happy to stick to that (even though if taken literal it may not be correct, but I am no software engineer and can't be bothered arguing semantics here) :)

Anyways, I was just pointing out how handy the Linked Tunnels feature of LabVIEW is - I think its great.

Oops I forgot. You ab use it as one by firing off ValSig biggrin.gif (Been known to do that myself on occasions....lol).

But Linked tunnels work on it too

Hey, that was one time, and...

Link to comment

Really? Then what do you call something that looks like this?

Well. If "idle" has a plethora others (which I strongly suspect -how many?). I'd call it a mess laugh.gif

But from the list I'd go for SM with event structure in the same sense that I'd go for a SM with an emergency stop, SM with foot switch and, indeed, any input stimulus to the actual state-machine.

Hey, that was one time, and...

I know. 'twas a bit below the beltrolleyes.gif. Especially because there is a very good example of it in the SQLite examples.

Link to comment

QFT. :star:

Maintaining data between loop iterations and carrying it through the case structure doesn't make the loop a state machine. It just makes it a loop with data you want to persist between iterations. It *has* state, but it's not necessarily a state machine.

The OP mentioned a "simple state machine," which I interpret as the enum-into-a-case-structure kind. For that the shift register is the best way to go.

In theory yes, but in practice we should keep in mind the nautre of LV and not "drink the kool-aid" and expect LV to do our thinking for us.

Performance!

There are code construct that will absolutely freak out LV's inplaceness algoithm in which case it exercises the default rule "if not sure copy the buffer". Complex clusters seem to encounter these issues more often than the simple data structures and as LV evolves, where the in-placeness freaks, can change from version to version. So putt large data structures in a cluster in a SR and passing it in and out of sub-VI's can bite us.

Two branches off that idea:

"The key the key and nothing but the key so help me Codd."

LVOOP

LVOOP first. It seems that Aristos and his team but some excellent thought into the LVOOP data strutures. Mainitaining a class instance in a SR and invoking methods on the wire really "feel" like they are pointers.

Confesion time!

I screwed up in one of my apps and cast (using type cast) a LVOOP class as an array of the class by mistake. I was baffled by LV crashing and passed it to NI as a bug in the TDMS functions. After Aristos traced down MY ERROR, I fixed the code and all ws fine but what really clicked on the light bulb for me was that improperly cast wire ran through a mile of code with out causing a sinlge issue and it was only when it came time to actually acces the data inside the class wire (down in the TDMS functions) did the actual data make a difference.

This bug experience should me just how little the LVOOP stuff is touched.

Now back to Codd.

I have never officially studied Normalization rules, but I have learned some from my wife. I have tried to keep some of those idea in mind when I design my clusters thinking about the clusters as if they were tables. Applying normaliztion rules help me sperate data that has nothing to do with each other while grouping those that do. (part of this can overlap with OOP ideas I suspect). now returning to a point I made early in this thread, if a data structure is only used in a small fraction of the states, move that data to an AE so that it is not being carried around with other data that it has nothing to do with.

So yes, SR are the standard approach and seem perfect for LVOOP, but if you have a performance challenge staring you in the face, special attention should be given to who where and when they are touched.

Just trying to firm up my ideas,

Ben

  • Like 1
Link to comment

Really? Then what do you call something that looks like this?

I'm curious, in your opinion what is it that makes a QSM a QSM, and what changes would take that construct out of the definition of QSM? I'm working on a presentation for our local user group. "QSM" seems to mean something different to everyone and I'm trying to figure out what the essence of a QSM is.

Link to comment

Performance!

So yes, SR are the standard approach and seem perfect for LVOOP, but if you have a performance challenge staring you in the face, special attention should be given to who where and when they are touched.

Excellent points Ben. I freely admit optimizing for performance is not something I have much experience with. In fact, I tend to follow the rule, "first make it work, then make it fast," even though that isn't always the fastest way to the solution.

Link to comment

Excellent points Ben. I freely admit optimizing for performance is not something I have much experience with. In fact, I tend to follow the rule, "first make it work, then make it fast," even though that isn't always the fastest way to the solution.

Many of my apps require high speed as req #1. My slaes team seem to be able to find those projects that "almost work" but perfomance is lacking. There are at least three dedicated developers in my office that are working projects that started out as "fix the preformance" to start out projects. years ago (whwn I was just a wee-G-babe) the big boss lamented durring a meeting "why do so many of our apps suffer from performance?". So now we design for speed and we seldom here about perfomance thses days.

The actual work process flow differe little from not keeping an eye on performance. VI development starts out with simple questions; 1) How large are the data sets for this VI going to to be? 2) How often is this going to have to run?

If the datasets are small and the code runs infrequently, just code away. If the code could affect performance, approach it delicately.

Take care,

Ben

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.