LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Combining Map and arrays?

Hi!

 

In my research to better handle and display data, I came across the function Map which is a bit new to me. If I understood well it is more efficient than arrays for accessing / editing data than arrays.

To me, it makes it also easier to look for specific info, instead of dealing with indexes and a cluster of different arrays that could be complex to refer to, a key that has a direct name makes it easier for a lot of reasons: Displaying info; Avoiding case structure with a bundle/unbundle of a cluster to retrieve the proper info etc.

But the thing is, I still have to deal with arrays because I'd like to display some data in graphs, but some other not. Now the issue is that Map need to have the same data type as values, but does it make sense to have a map with variants as values in which I can feed different type of data: Array of dbl ; a cluster of specific info; etc.?

From the examples I've seen (and my unsuccessful research on this forum) it seems that maps are really not designed for this, but more for Key associated with One single value (a string or a numeric for instance)

 

My question is related to this other post I published a few days ago: 

https://forums.ni.com/t5/LabVIEW/Data-handling-sharing-across-an-application/m-p/4228391#M1227658

 

Thank you in advance for your help.

Vinny

0 Kudos
Message 1 of 33
(4,390 Views)

@VinnyAstro wrote:

If I understood well it is more efficient than arrays for accessing / editing data than arrays.

Access to arrays can be much more efficient than map access. And it often is.

 

Getting an array element by it's index is very fast, O(1).

 

Getting an element from a map by it's key is slower, O(log(n)).

 

So, if you're key is (can be) an index in an array, an array will be the absolute winner (my miles).

 

However, if you have two arrays (keys and values), you need to search one array, then the other. Then a map will be faster (map: O(log(n)) vs array O(n). However, searching an ordered arrays is also O(log(n)). Both maps and ordered arrays use a binary search...

 

Maps are (in my experience) much slower to copy. This makes sense. Each map element needs to store a pointer to it's left and right element in the tree. This will add 8 or 16 bytes to each element, which could be significant.

 

So in general I have to disagree. It is very specific to the use case.

 

Maps are more convenient than two ordered arrays. For instance, when inserting into two ordered arrays, you need to check if the element is there. A map will do this by nature. However, having duplicates could be a feature 😂. You won't have this option in a map.

 


@VinnyAstro wrote:

To me, it makes it also easier to look for specific info, instead of dealing with indexes and a cluster of different arrays that could be complex to refer to, a key that has a direct name makes it easier for a lot of reasons: Displaying info; Avoiding case structure with a bundle/unbundle of a cluster to retrieve the proper info etc.


I agree, maps will often be more convenient.

 


@VinnyAstro wrote:

But the thing is, I still have to deal with arrays because I'd like to display some data in graphs, but some other not. Now the issue is that Map need to have the same data type as values, but does it make sense to have a map with variants as values in which I can feed different type of data: Array of dbl ; a cluster of specific info; etc.?

From the examples I've seen (and my unsuccessful research on this forum) it seems that maps are really not designed for this, but more for Key associated with One single value (a string or a numeric for instance)


Variants are the opposite of fast.

 

Also, if you're going to set\get large amounts of data from a map (or array), it will be hard to avoid copies.

 

I'd use store data.lvclass in the map\array. The data.lvclass will have a child for each supported data type, e.g. array of double.lvclass. The class can have methods to display itself in a graph, etc.

 

You can hack things. E.g. store flattened DVRs in the map\array. This will be fast. And totally incomprehensible. Before using the DVR, you have to cast it to a DVR of the right type (things might crash if you don't). This will require some DIY polymorphism...

 

The classes described earlier could contain DVRs... I'd avoid that, but it would be much better than the 'raw' DVR solution, as the class types protect their implementation (aka encapsulation). You can even mix things up, use a DVR in some childs, and no DVR in others..

0 Kudos
Message 2 of 33
(4,361 Views)

@VinnyAstro wrote:

But the thing is, I still have to deal with arrays because I'd like to display some data in graphs, but some other not. Now the issue is that Map need to have the same data type as values, but does it make sense to have a map with variants as values in which I can feed different type of data: Array of dbl ; a cluster of specific info; etc.?


Seems to me you're looking for a general storage thingy.

 

Careful what you wish for, you might get it. This often turns into the application's garbage can, leaving a mess anywhere it's used.

 

Putting everything on a pile might seem convenient, but you will end up with a pile...

 

Keeping things separated takes more work to get things organized, but the result is that things are, unlike my desk, organized. This is also known as divide and concur. It's much related to principles like decoupling, encapsulation and single responsibility.

0 Kudos
Message 3 of 33
(4,350 Views)

wiebe@CARYA wrote:


Variants are the opposite of fast.

...

I'd use store data.lvclass in the map\array. The data.lvclass will have a child for each supported data type, e.g. array of double.lvclass.

 


In my experience I wouldn't think Variants are any slower than using "data" classes.  The opposite of fast would be flattening to string.

0 Kudos
Message 4 of 33
(4,343 Views)

@VinnyAstro wrote:

From the examples I've seen (and my unsuccessful research on this forum) it seems that maps are really not designed for this, but more for Key associated with One single value (a string or a numeric for instance)


Before they created Maps, people often used Variant Attributes for similar applications.  You might search on examples of "Variant Attributes".   Attributes are like Maps but always String names and Variant values.

0 Kudos
Message 5 of 33
(4,338 Views)

@VinnyAstro wrote:

Hi!

 

In my research to better handle and display data, I came across the function Map which is a bit new to me. If I understood well it is more efficient than arrays for accessing / editing data than arrays.

To me, it makes it also easier to look for specific info, instead of dealing with indexes and a cluster of different arrays that could be complex to refer to, a key that has a direct name makes it easier for a lot of reasons: Displaying info; Avoiding case structure with a bundle/unbundle of a cluster to retrieve the proper info etc.

But the thing is, I still have to deal with arrays because I'd like to display some data in graphs, but some other not.


BTW, my go-to solution for handling and displaying data is SQLite.  Data storage is an SQLite database file and all displays query from the database.  SQL queries have capabilities that would take a huge effort to do with any LabVIEW data structure.

0 Kudos
Message 6 of 33
(4,333 Views)

@drjdpowell wrote:

wiebe@CARYA wrote:


Variants are the opposite of fast.

...

I'd use store data.lvclass in the map\array. The data.lvclass will have a child for each supported data type, e.g. array of double.lvclass.

 


In my experience I wouldn't think Variants are any slower than using "data" classes.  The opposite of fast would be flattening to string.


Well, I've never benchmarked that.

 

Classes should be just pointers. Getting a class from a map probably always copies the data, but this should be a fast data copy.

 

Variant To Data and Unflatten do type checking. With Variant To Data and Unflatten things can go wrong, and the error handling should (at least theoretically) should give overhead that a data class doesn't have.

0 Kudos
Message 7 of 33
(4,330 Views)

wiebe@CARYA wrote:

@drjdpowell wrote:

wiebe@CARYA wrote:


Variants are the opposite of fast.

...

I'd use store data.lvclass in the map\array. The data.lvclass will have a child for each supported data type, e.g. array of double.lvclass.

 


In my experience I wouldn't think Variants are any slower than using "data" classes.  The opposite of fast would be flattening to string.


Well, I've never benchmarked that.

 

Classes should be just pointers. Getting a class from a map probably always copies the data, but this should be a fast data copy.

 

Variant To Data and Unflatten do type checking. With Variant To Data and Unflatten things can go wrong, and the error handling should (at least theoretically) should give overhead that a data class doesn't have.


(The forum doesn't allow me to edit anymore, when I click options the page goes to the top...)

 

There is (I've noticed) overhead in calling DD methods on those classes. The overhead is small, but especially methods that hardly do anything (Get Type, Get Size, etc.) this overhead does add up.

0 Kudos
Message 8 of 33
(4,327 Views)

Both Variants and Classes involve overhead.  I don't know which is higher, but in both cases the overhead is not "the opposite of fast".  Both can carry large data structures by pointer and thus without a necessary copy (unlike flattening to string that must always copy, and can be very slow).

0 Kudos
Message 9 of 33
(4,318 Views)

Thanks for your inputs!

Unfortunately this forum doesn't allow multi-quoting so I'll try to answer everyone:

 


wiebe@CARYA wrote:

@VinnyAstro wrote:

But the thing is, I still have to deal with arrays because I'd like to display some data in graphs, but some other not. Now the issue is that Map need to have the same data type as values, but does it make sense to have a map with variants as values in which I can feed different type of data: Array of dbl ; a cluster of specific info; etc.?


Seems to me you're looking for a general storage thingy.


Storage wouldn't be the right term, I don't want to store all the info permanently, but yes, this is kinda what I'm looking for.

 

I have a bunch of data, some of them I want them in an array to display as an XY graph (Absolute time vs Amplitude) as well as "The last value" in a digital display; but some of them don't make sense to display in an XY graph (e.g. a status cluster containing a boolean, a numeric and a string) for which I'm only interested in the very last value..

Every separate data comes already with an hexadecimal ID (Which I used to convert the data in a case structure)

 

This is my current idea iteration:

VinnyLaTaupe_2-1652354199074.png

 

 

And then comes my question:

In the case "New TM" in the MHL queue, should I

  • Use a Variant to Data in a case structure based on the TM ID received and store the data in big cluster which I would send periodically for Log/Display
  • Use a map with my TM_ID as a key and send this map to display/store periodically.

 

But according to what you're telling me wiebe@CARYA, even the first point wouldn't be very effective in term of performances. And even, I'm not sure how I would be able to send only the desired data (and not the cluster) to display/log given that some data will sometimes not be needed and requested.

 

I can try to look into Data classes, but I'm not yet trained to work with LVOOP unfortunately...

 

 


@drjdpowell wrote:

Before they created Maps, people often used Variant Attributes for similar applications.  You might search on examples of "Variant Attributes".   Attributes are like Maps but always String names and Variant values.


I've seen this yes, would this be more adapted to what I'm looking for above?

 

I will also look into SQL, have no idea what this is yet.

 

 

0 Kudos
Message 10 of 33
(4,303 Views)