LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Formatting Array to String challenge


@altenbach wrote:

@raphschru wrote:

If using subVIs from vi.lib is allowed:


And if not (or even in general!), we would probably do this.

 

altenbach_0-1736366852785.png

 

 

(Of course we must be assume that there is an even number of elements)


I like this variation of that:

try fmt 4.vi Snippet.png

0 Kudos
Message 21 of 27
(322 Views)

Not the simplest, not the most efficient. Just having fun with recursive vi (LV2021)

 

Ben

0 Kudos
Message 22 of 27
(260 Views)

Using search and replace twice
search and replace.png

0 Kudos
Message 23 of 27
(255 Views)

If you would like to go with "hardcore" way, then something like that:

 

ARRTOSTRING_API void arrayToFormattedString(TD1Hdl LVarr, LStrHandle LVstr)
{
	char num1[12];
	char num2[12];

	int size = (*LVarr)->dimSize;
	int* arr = (*LVarr)->elt;

	//in worst case we need 25 chars for each pair
    MgErr err = NumericArrayResize(uB, 1, (UHandle*)&(LVstr), (size/2)*25);
	if (err != noErr) return; // Not enough memory
    LStrLen(*LVstr) = (size / 2) * 25;
    char* ptr = (char*)LStrBuf(*LVstr);
	size_t saved_ptr = (size_t)ptr;

    for (int i = 0; i < size; i += 2) {
		if (i) { memcpy(ptr, ", ", 2); ptr += 2; } // Add separator between pairs
        itoa(arr[i], num1, 10);
        itoa(arr[i + 1], num2, 10);
        memcpy(ptr, num1, strlen(num1)); ptr += strlen(num1);
        memcpy(ptr++, "/", 1);
        memcpy(ptr, num2, strlen(num2)); ptr += strlen(num2);
    }
    int count = (size_t)ptr - (size_t)saved_ptr;

    err = NumericArrayResize(uB, 1, (UHandle*)&(LVstr), count);
    LStrLen(*LVstr) = count;
}

 

The only advantage — this code is roughly 5x times faster than native LabVIEW code:

snippet.png

Result:

Screenshot 2025-01-11 08.25.26.png

But it only makes sense if you have a real performance bottleneck here.

0 Kudos
Message 24 of 27
(239 Views)

@paul_a_cardinale wrote:

@altenbach wrote:

@billko wrote:

I'd actually rather see how Rube-ish we can get it.  😉


challenge accepted....

 

Rubeformatting.png


Well, I suppose that's a nice try; but it doesn't hold a candle to some of the psychotic code that I've seen over the decades.


Well, the RG part is subtle and mostly in the crazy way to build the string inside the formatting via shift register. While it looks innocent, this has always been significantly slower that e.g. autoindexing followed by concatenating. I also have the nagging feeling that constantly swapping the formatting introduces a few more flaming hoops to the compiler optimization.

 

0 Kudos
Message 25 of 27
(215 Views)

@Andrey_Dmitriev wrote:

 

But it only makes sense if you have a real performance bottleneck here.


And if I will use SSE2 version of itoa and avoid memcopies with running pointer:

 

    ptr += i32toa_sse2(arr[0], ptr);
	*ptr++ = '/'; // First pair
    ptr += i32toa_sse2(arr[1], ptr);

    for (int i = 2; i < size; i += 2) {
        *ptr++ = ','; *ptr++ = ' '; // Add separator between pairs
        ptr += i32toa_sse2(arr[i], ptr);
        *ptr++ = '/';
		ptr += i32toa_sse2(arr[i + 1], ptr);
    }

(I added strlen at the end of i32toa_sse2).

 

Then it will be over 20x times faster:

Screenshot 2025-01-11 22.24.56.png

I'm not sure about the real purpose of this challenge - whether it's in favor code 'compactness' or performance. This is just a fun experiment.

0 Kudos
Message 26 of 27
(200 Views)

@Andrey_Dmitriev wrote:

@Andrey_Dmitriev wrote:

...

I'm not sure about the real purpose of this challenge - whether it's in favor code 'compactness' or performance. This is just a fun experiment.


Originally, I had a need for the code.  Although I could think of a variety of ways to do it, I wondered if someone could come up with a particularly nice* way of doing it.  In the interim, I have eliminated my need for the code (the formatting now happens before the data are bundled into an array).

 

* "nice" as in: looks good on the block diagram.

0 Kudos
Message 27 of 27
(193 Views)