Is it possible to optimize this?

I’m currently making a buffer compression algorithm to store builds in datastore more easily but it is very slow on big buffers and I’ve found this function which takes 50% of the decode computation time, how could I optimize it ?

function BufferOperations.ReadBinaryStringBuffer(b: buffer)
	-- Variables
	local bufferLen = buffer.len(b)
	local lastByteBits = buffer.readu8(b, bufferLen - 1)
	local outputString = {}
	
	-- Main
	for byteIndex = 0, bufferLen - 2 do
		local byte = buffer.readu8(b, byteIndex)
		local bitsToRead = 8

		if byteIndex == bufferLen - 2 then
			bitsToRead = lastByteBits
		end
		
		for bitPos = 0, bitsToRead - 1 do
			table.insert(outputString, bit32.extract(byte, bitPos))
		end
	end
	
	-- Returning
	return table.concat(outputString)
end
3 Likes

I would just wait for Roblox to enable the EncodingService which offers native implemention that will run faster than you could ever make it in Luau
https://create.roblox.com/docs/reference/engine/classes/EncodingService

2 Likes

Something that come to mind is using buffer.readu32 calls for the largest segment of the string, so you read multiple bytes at once and do fewer iterations. Another idea is to manually maintain and pass the size/length of the buffer, instead of doing buffer.len calls and scanning over the entire thing every time. You can also use table.create(n) for the outputString, since, if I’m not mistaken, the size of the table can be precomputed(it doesn’t rely on complex behavior).

4 Likes

Thanks
I didn’t know about this I might use it in the future !

1 Like

Also you can insert --!native at the top of script. This will speed up the script a bit (in some situations).
See Luau Native Code Generation Preview [Studio Beta]

2 Likes

The opposite, actually; due to Roblox’s dumb tendency of making everything a method and probably Luau → Instance API bridge overhead, Luau implementation will be MUCH MUCH faster thanks to native code generation that will actually work and be compiled in this case.

Yes, it will generate native code in this case; I fact-checked it

Nope, sadly the compiler is too stupid; it won’t.
It has NEWTABLE and DUPTABLE opcodes that always go to waste. Even if the table.create(n) argument passed is static, the compiler won’t generate the NEWTABLE opcode instead, and it’s such a shame.

Like it makes 100% sense for table.create(100) to be NEWTABLE R0 100 0 but nope, the compiler is an idiot.

1 Like

They just enabled the service, we can test it empiricially :slightly_smiling_face:

Also, my original reply was based off the same thread:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.