08-07-2024 02:59 PM
I'm refactoring an application that has many classes. I'd like it to load faster and build faster. I figured lvlibp files would be the way to make this happen.
I finally managed to get the project divided up into about 5 lvlibp files. Now the amount of memory consumed when the lvlibp file is pulled into a project is 3 times more than was consumed by the raw class files alone. I don't see any duplicate dependencies in the project, get no conflicts, and no errors when opening VIs.
I assume that vi.lib files are being duplicated into each of the lvlibp files and that's causing a large amount of duplicated resources. Is there a way I can avoid this? I already checked the boxes to exclude dependent PPLs. I found the tool VI named "Get Exported File List.vi". That indicates that there are no VIs from VI.lib in my PPL. I also don't see anything in the PPL that isn't from my source class library.
However, while the PPL is being built, I can go into the temporary folder that is generated during the build and I see a bunch of VI.lib files in there.
Does anyone have some suggestions for me on how I can prevent my PPLs from taking up 3x the memory of their origin source code?
08-07-2024 03:45 PM
How are you checking the amount of memory that's being consumed when you add the PPL to the project? Also how much is the memory actually increasing?
08-07-2024 04:19 PM
About using "Get Exported File List.vi"....
Per this page in NI's documentation, "Exported VIs are VIs in project libraries with a public access scope or VIs in LabVIEW classes with a public or protected access scope".
Note that neither of those categories covers dependencies of those VIs.
Suggestion: Create a small VI and add a copy of it to each of your LVLIBPs. The VI should just contain a call to the property node "Application.Application.All VIs in memory":
Then output the string array it produces.
Compile that into a LVLIBP and run it from outside the LVLIBP. You should see a list of everything packed in the VI, whether it meets the "Exported" definition or not.
08-07-2024 05:37 PM - edited 08-07-2024 05:48 PM
Libraries, You know, as a child I used to go to the Library all of the time, It was a public Library in South St. Paul Minnesota. You wouldn't believe how many things were available there! I could; read the local newspaper (even going back decades on microfishe,) find fiction written by A. E. Hitchcock, browse Encyclopedia Brittanica (or look it up in the Funk and Wagnel for those of you who remember Rowan and Martin!) peruse the Chilton's manual for the family "grocery-getter" (a Ford LTD Sation Wagon!) Or even read a novel by Ayn Rand! (Who is John Gault?)
That is not what a Library means in software development. In Software development a Library has a very specific purpose.
I cannot remember the last time I developed even a minor project that depended on as few as 5 libraries.
Double check the coherence within your libraries and refactor accordingly. 😉
08-07-2024 06:28 PM
Wow, that's super useful! I actually tried using that exact function, but I didn't put it inside the library. I had no idea it would show me different things when called from inside the library. This confirms that I am in fact having VI.lib stuff show up in the compiled library.
This is probably a dumb question but, how do I make that stop happening? I have a hierarchy of libraries now, and each one calls VI Lib, but also calls the downstream library. How do I make it so that the libraries are all dependent on VI.Lib instead of making their own copy of the data?
I get that a library is supposed to be a functional deliverable piece of code, but I've watched videos where people have a hundred and fifty of these in an application. I must be doing something dumb if I'm getting VI lib copied into each of mine.
08-08-2024 07:02 AM
@Shane-C wrote:
I get that a library is supposed to be a functional deliverable piece of code, but I've watched videos where people have a hundred and fifty of these in an application. I must be doing something dumb if I'm getting VI lib copied into each of mine.
When you build a PPL, it will import any dependencies not in another PPL into itself. So, yes, you will have "duplicate" functions from vi.lib in your PPLs. It will just be the object data, but they are there. But because they are in a single file and already compiled, they will load fast and will speed up your builds.
08-08-2024 01:06 PM
@Shane-C wrote:
Wow, that's super useful! I actually tried using that exact function, but I didn't put it inside the library. I had no idea it would show me different things when called from inside the library. This confirms that I am in fact having VI.lib stuff show up in the compiled library.
This is probably a dumb question but, how do I make that stop happening? I have a hierarchy of libraries now, and each one calls VI Lib, but also calls the downstream library. How do I make it so that the libraries are all dependent on VI.Lib instead of making their own copy of the data?
I get that a library is supposed to be a functional deliverable piece of code, but I've watched videos where people have a hundred and fifty of these in an application. I must be doing something dumb if I'm getting VI lib copied into each of mine.
As crossrulz says, the only way to not have a given dependency inside of one PPL is to have it inside another.
If you see a place where someone has 150 PPLs in an application, they are almost certainly doing one of a few different things (or some combination of them).
First possibility, each PPL only contains a tiny bit of code. Maybe it's something like a test engine, and each PPL is just a single test step which contains the code just to do one simple operation on one instrument.
Second, they could be focused a lot on reducing overhead. There are a lot of VIs in VI.lib and other places that contain very little actual code, and often some of that is tied to optional inputs that you might not even use. For instance, if instead of using a call to "Clear errors" in vi.lib, if I just use this:
Doing that removes a dependency from VI.lib and also the small overhead of calling it. Do that with enough VIs and it can make a meaningful difference.
Third, use less of VIs that are unique instances each time they are used. This means Malleable and Express VIs. Each one of those you put on a block diagram is its own separate copy, not a single copy shared by everything in the PPL.
Fourth, build using a PPL hierarchy. Build one or more PPLs first that have no dependencies on other PPLs. Then have a 2nd level that calls functions in those PPLs as much as possible instead of external sources. Then a 3rd level that calls functions from the first 2 levels, and so on.
Fifth, use less classes. Classes in LabVIEW may seem like fancy libraries, but no matter what options you use, every class always loads all of its members into memory as soon as the first one is referenced in any way. So if you use one type definition that is a cluster with one element being a member of a class and nothing else in your PPL references, then any PPL built with that in it might load all 100 member VIs of that class and all 300 dependencies of that class from VI.lib or other sources.
There's probably more I'm not thinking of at the moment either...
08-09-2024 07:58 AM
@Kyle97330 wrote:Fourth, build using a PPL hierarchy. Build one or more PPLs first that have no dependencies on other PPLs. Then have a 2nd level that calls functions in those PPLs as much as possible instead of external sources. Then a 3rd level that calls functions from the first 2 levels, and so on.
Fifth, use less classes. Classes in LabVIEW may seem like fancy libraries, but no matter what options you use, every class always loads all of its members into memory as soon as the first one is referenced in any way. So if you use one type definition that is a cluster with one element being a member of a class and nothing else in your PPL references, then any PPL built with that in it might load all 100 member VIs of that class and all 300 dependencies of that class from VI.lib or other sources.
These two are the really important ones as they are the key to making a plugin architecture.
08-09-2024 09:09 AM
@Shane-C wrote:
I'm refactoring an application that has many classes. I'd like it to load faster and build faster. I figured lvlibp files would be the way to make this happen.
According to Darren, the 2nd fastest and a lot easier to manage are LLBs