Moderators IIYAMA Posted April 25, 2020 Moderators Share Posted April 25, 2020 (edited) 4 hours ago, majqq said: Hi. So after all i've decided to play with bone attach once again, had to fix CJ skin bug, and decided to squeeze out even more performance CPU: i5-9400F 1 attached object: 100 attached objects: Even after all those optimisations, it is still pretty high What is the usage of the initial version compared to the current version? Also, I might be able to squeeze even more out of it, if you want that. Edited April 25, 2020 by IIYAMA Link to comment
Scripting Moderators ds1-e Posted April 25, 2020 Author Scripting Moderators Share Posted April 25, 2020 (edited) 8 hours ago, IIYAMA said: Even after all those optimisations, it is still pretty high What is the usage of the initial version compared to the current version? Also, I might be able to squeeze even more out of it, if you want that. I've received different results when testing them one at once. In 2019 i had completely different CPU (and bad PC with Windows 7 - now i'm using Windows 10), it was AMD Athlon II x2 2.70 GHz. bone_attach_original stands for main version which uses pairs, and coroutines. bone_attach_2k19 stands for "optimized" version which i was pretty sure, that it works well (seems i was wrong), uses for i = 1, #tableSize do loop, localized math methods, all tables, all resource functions. bone_attach_2k20 stands for version which i've rewrited today. Uses aswell for i = 1, #tableSize do loop, localized math methods, all tables, all resource functions, mostly called functions (setElementPosition/getElementPosition; setElementRotation/getElementRotation), variables inside of functions scope are declared in main one (they aren't recreating every frame, so script just overwrite values - excluding one variable; i've exceeded upvalues limit - they aren't so fast as in function scope, but it's still better solution to overwrite rather than create new ones - correct me if i'm wrong), however - between 2020 version and original; 2019 there's small (?) difference in logic, in newest version i've implemented fix for CJ skin, which uses math.round method (solution from haron4igg - https://forum.multitheftauto.com/topic/57349-help-attachelementtobone/?tab=comments#comment-661478), besides that, data is stored in sub-tables (+ 1 indexing count) - by data i mean attachments, bone 0/T/F offsets. However, i've greatly reduced count of accessing render data. Latest difference between 2020 version and others is that, it doesn't use server-side at all (creates objects via client-side and attach them directly there) Used to be: local element = bone_attach[i][1] local ped = bone_attach[i][2] local attached_x = bone_attach[i][4] local attached_y = bone_attach[i][5] local attached_z = bone_attach[i][6] local attached_rx = bone_attach[i][7] local attached_ry = bone_attach[i][8] local attached_rz = bone_attach[i][9] Now it's: CLocalRenderData = CLocalRenderAttachments[i] local CLocalRenderElement = CLocalRenderData[1] CLocalRenderPed = CLocalRenderData[2] CLocalRenderBone = CLocalRenderData[3] CLocalRenderAttachX = CLocalRenderData[4] CLocalRenderAttachY = CLocalRenderData[5] CLocalRenderAttachZ = CLocalRenderData[6] CLocalRenderAttachRX = CLocalRenderData[7] CLocalRenderAttachRY = CLocalRenderData[8] CLocalRenderAttachRZ = CLocalRenderData[9] IPB results: 50 objects: 100 objects: Maybe i made something wrong, in 2019, honestly, i don't know Edited April 25, 2020 by majqq 1 Link to comment
Moderators IIYAMA Posted April 25, 2020 Moderators Share Posted April 25, 2020 (edited) 1 hour ago, majqq said: However, i've greatly reduced count of accessing render data. I see you have optimised the loop cycles to the bone. But there is something you haven't tried yet, which can improve performance of 100 objects to a % of that, depending on the context. In your current code, you are making full cycles, which changes the usage of the resource by the amount of objects. But what if you could only make the necessary cycles? Prepare render cycle | | \/ bone_attach \ / Add each item to the queue, except for the once that are already in the render table, based on a state. QUEUE \ / Loop through 50 items each frame QUEUE [50 elements] \ / Is element streamed in? If YES, then add the item to the render table. If YES or NO, then table.remove. Give the item a state that it is already in the render table. bone_attach_render | | \/ Re-do the cycle after X ms This concept allows you to reduce big looping cycles. Which also allows you to even render 1000 objects, as long as the peds/players are not inside of the same area. These are not all the steps, there are some more which are related to 'destroyed' and 'streamed-out' elements. Edited April 25, 2020 by IIYAMA 2 Link to comment
Tekken Posted April 26, 2020 Share Posted April 26, 2020 @IIYAMA will you make a simple example as I don't really understand the idea, thank you. 1 Link to comment
Moderators Popular Post IIYAMA Posted April 26, 2020 Moderators Popular Post Share Posted April 26, 2020 5 minutes ago, Tekken said: @IIYAMA will you make a simple example as I don't really understand the idea, thank you. I don't think it can be a simple example, but here you go. local bone_attach = {} local bone_attach_render = {} local queue = {} local queueProcessStatus = false local queueNextCycleTime = 0 local tableRemove = table.remove function prepareQueue () queueProcessStatus = true for i=1, #bone_attach do local item = bone_attach[i] if not item.rendered then queue[#queue + 1] = item end end end function processQueue () for i=#queue, math.max(#queue - 50, 1), -1 do local item = queue[i] local element = item.element if isElement(element) and isElementStreamedIn(element) then item.rendered = true bone_attach_render[#bone_attach_render + 1] = item end tableRemove(queue, i) end if #queue == 0 then queueProcessStatus = false end end addEventHandler("onClientRender", root, function () for i=#bone_attach_render, 1, -1 do local item = bone_attach_render[i] local element = item.element if isElement(element) and isElementStreamedIn(element) then else item.rendered = false tableRemove(bone_attach_render, i) end end -- cycle management local timeNow = getTickCount() if not queueProcessStatus then if timeNow > queueNextCycleTime then prepareQueue() queueNextCycleTime = timeNow + 3000 end else processQueue () end end) 3 1 Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now