I am parallelizing unzipping of tables to take up less time.
I am using a messaging system where the main script sends messages to the unzippers, and they send one back while the main script listens for the messages. This works quite well but for some reason the return messages don’t get received until all the unzippers have finished their parallel work. This leads to an unnecessary time waste. It would work better if the messages went through while it is in parallel.
I tried using an event to transmit the data, but they don’t work in parallel, and serializing the code didn’t work out. Using a shared table did resolve the problem, but putting the massive tables into the shared table took more time than sending the chunks back using messages and putting them into a normal table.
You can see from the micro profiler that the receiving section happens after the entire unzipping part is done. I want the messages to be received during the unzipping. (When the messages are sent)
You can see it more clearly in the output, where all the numbers are printed at once, and then they are received all together, rather than being more spread out.
ServerCode
game.ReplicatedStorage.GetChunks.OnServerInvoke = function(Player,ChunksWanted)
debug.profilebegin("GetToUnzip")
table.clear(Unzipped)
local ToUnzip={}
for i,column in pairs(ChunksWanted) do
for o,chunk in pairs(column) do
local ServerChunkX=math.ceil(i/SmallChunks)
local ServerChunkZ=math.ceil(o/SmallChunks)
if not ToUnzip[ServerChunkX] then
ToUnzip[ServerChunkX]={}
end
ToUnzip[ServerChunkX][ServerChunkZ]="TU"
end
end
debug.profileend()
debug.profilebegin("Send Messages")
local Messages=0
for i,column in pairs(ToUnzip) do
for o,chunk in pairs(column) do
Messages+=1
Actors[CurrentActor]:SendMessage("Unzip",world[i][o],i,o)
CurrentActor+=1
if CurrentActor>#Actors then
CurrentActor=1
end
end
end
debug.profileend()
local MessageReturns=0
script.Parent:BindToMessageParallel("ReturningChunk",function(Chunk,posX,posZ,num)
print("Recived "..num)
debug.profilebegin("SettingChunk")
MessageReturns+=1
if not Unzipped[posX] then
Unzipped[posX]={}
end
Unzipped[posX][posZ]=Chunk
debug.profileend()
end)
task.wait()
local ToRender={}
for i,column in pairs(ChunksWanted) do
for o,chunk in pairs(column) do
debug.profilebegin("Getting chunk "..i..","..o)
local ServerChunkX=math.ceil(i/SmallChunks)
local InsideChunkX=i-(ServerChunkX-1)*SmallChunks
local ServerChunkZ=math.ceil(o/SmallChunks)
local InsideChunkZ=o-(ServerChunkZ-1)*SmallChunks
local UnzippedChunk=Unzipped[ServerChunkX][ServerChunkZ][InsideChunkX][InsideChunkZ]
if not ToRender[i] then
ToRender[i]={}
end
ToRender[i][o]=UnzippedChunk
debug.profileend()
end
end
debug.profilebegin("Sending Render")
return ToRender
end
Parallel Code
local http=game:GetService("HttpService")
script.Parent:BindToMessageParallel("Unzip",function(Chunk,PositionX,PositionZ)
local UnzippedChunk=http:JSONDecode(Chunk)
local num=math.random(1,100)
game.ServerScriptService.Actor:SendMessage("ReturningChunk",UnzippedChunk,PositionX,PositionZ,num)
print(num)
end)
I used 12 unzippers in this test (the small code above)
To reiterate. How do I get the messages to go through during the parallel processing, and if not, what is a suitable work around?
Any Response is appreciated!
I also have more information on this in my code review thread about this: