Skip to content

Commit ab8de0b

Browse files
committed
Lua 'Versus' Submodule (Code speed comparison)
1 parent fd1c038 commit ab8de0b

File tree

1 file changed

+235
-0
lines changed

1 file changed

+235
-0
lines changed

lua/blobsprofiler/shared/modules/bp_lua.lua

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
if SERVER then
22
util.AddNetworkString("blobsProfiler:sendLua")
3+
util.AddNetworkString("blobsProfiler:sendLua_versus")
34
end
45

56
blobsProfiler.RegisterModule("Lua", {
@@ -103,6 +104,7 @@ blobsProfiler.RegisterSubModule("Lua", "Globals", {
103104

104105
blobsProfiler.RegisterSubModule("Lua", "Execute", {
105106
Icon = "icon16/script_code.png",
107+
OrderPriority = 2,
106108
CustomPanel = function(luaState, parentPanel)
107109
local dhtmlPanel = blobsProfiler.generateAceEditorPanel(parentPanel)
108110

@@ -133,6 +135,174 @@ blobsProfiler.RegisterSubModule("Lua", "Execute", {
133135
end
134136
})
135137

138+
local function prettyProfilerTimeFormat(seconds)
139+
if seconds >= 0.5 then
140+
return string.format("%.2fs", seconds)
141+
else
142+
return string.format("%.6fms", seconds * 1000)
143+
end
144+
end
145+
146+
local function SetupResultsPanel(parentPanel, numIterations, lcTotalTime, lcMin, lcMax, rcTotalTime, rcMin, rcMax)
147+
parentPanel.stopCompare = false
148+
149+
if parentPanel.resultsPanel and IsValid(parentPanel.resultsPanel) then
150+
parentPanel.resultsPanel:Remove()
151+
parentPanel.resultsPanel = nil
152+
end
153+
154+
parentPanel.resultsPanel = vgui.Create("DPanel", parentPanel)
155+
parentPanel.resultsPanel:Dock(BOTTOM)
156+
parentPanel.resultsPanel:SetTall(70)
157+
158+
local colorGreen = Color(0,136,0)
159+
local colorRed = Color(255,0,0)
160+
161+
parentPanel.resultsPanel.Paint = function(s,w,h)
162+
draw.SimpleText("Total execution time: ".. prettyProfilerTimeFormat(lcTotalTime), "DermaDefault", 5, 5, lcTotalTime<rcTotalTime and colorGreen or colorRed, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
163+
draw.SimpleText("Slowest execution time: ".. prettyProfilerTimeFormat(lcMax), "DermaDefault", 5, 20, lcMax<rcMax and colorGreen or colorRed, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
164+
draw.SimpleText("Fastest execution time: ".. prettyProfilerTimeFormat(lcMin), "DermaDefault", 5, 35, lcMin<rcMin and colorGreen or colorRed, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
165+
draw.SimpleText("Average execution time: ".. prettyProfilerTimeFormat((lcTotalTime/numIterations)), "DermaDefault", 5, 50, ((lcTotalTime/numIterations)<(rcTotalTime/numIterations)) and colorGreen or colorRed, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
166+
167+
local dividerPos = parentPanel.codeContainer.m_DragBar:GetX()
168+
draw.SimpleText("Total execution time: ".. prettyProfilerTimeFormat(rcTotalTime), "DermaDefault", 5 + dividerPos, 5, lcTotalTime>rcTotalTime and colorGreen or colorRed, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
169+
draw.SimpleText("Slowest execution time: ".. prettyProfilerTimeFormat(rcMax), "DermaDefault", 5 + dividerPos, 20, lcMax>rcMax and colorGreen or colorRed, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
170+
draw.SimpleText("Fastest execution time: ".. prettyProfilerTimeFormat(rcMin), "DermaDefault", 5 + dividerPos, 35, lcMin>rcMin and colorGreen or colorRed, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
171+
draw.SimpleText("Average execution time: ".. prettyProfilerTimeFormat((rcTotalTime/numIterations)), "DermaDefault", 5 + dividerPos, 50, ((lcTotalTime/numIterations)>(rcTotalTime/numIterations)) and colorGreen or colorRed, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
172+
end
173+
end
174+
175+
blobsProfiler.RegisterSubModule("Lua", "Versus", {
176+
Icon = "icon16/application_cascade.png",
177+
CustomPanel = function(luaState, parentPanel)
178+
local leftCode = blobsProfiler.generateAceEditorPanel(parentPanel,[[local function addNumbers(a, b)
179+
return a + b
180+
end
181+
182+
local sum = addNumbers(5, 5)]])
183+
local rightCode = blobsProfiler.generateAceEditorPanel(parentPanel,[[local sum = 5 + 5]])
184+
185+
local codeContainer = vgui.Create("DHorizontalDivider", parentPanel)
186+
codeContainer:Dock(FILL)
187+
188+
codeContainer:SetLeft(leftCode)
189+
codeContainer:SetRight(rightCode)
190+
191+
codeContainer:SetLeftMin(0)
192+
codeContainer:SetRightMin(0)
193+
194+
-- Custom paint function for the drag bar
195+
codeContainer.m_DragBar.Paint = function(s, w, h)
196+
surface.SetDrawColor(0, 0, 0)
197+
surface.DrawRect(0, 0, w, h)
198+
end
199+
200+
local optionsContainer = vgui.Create("DPanel", parentPanel)
201+
optionsContainer:Dock(BOTTOM)
202+
optionsContainer:SetTall(50)
203+
204+
local iterationNumSlider = vgui.Create("DNumSlider", optionsContainer)
205+
iterationNumSlider:SetText("## of iterations")
206+
iterationNumSlider.Label:SetTextColor(Color(0,0,0))
207+
iterationNumSlider:SetMin(0)
208+
iterationNumSlider:SetMax(50000)
209+
iterationNumSlider:SetDecimals(0)
210+
iterationNumSlider:SetValue(1000)
211+
iterationNumSlider:Dock(TOP)
212+
iterationNumSlider:DockMargin(15,0,0,0)
213+
iterationNumSlider:DockPadding(0,0,0,5)
214+
215+
local runComparison = vgui.Create("DButton", optionsContainer)
216+
runComparison:Dock(BOTTOM)
217+
runComparison:SetText("Compare code")
218+
219+
runComparison.DoClick = function()
220+
if not parentPanel.stopCompare or parentPanel.stopCompare == false then -- Is this redundant? probably. I forget. my brain is mush.
221+
if parentPanel.resultsPanel and IsValid(parentPanel.resultsPanel) then
222+
parentPanel.resultsPanel:Remove()
223+
parentPanel.resultsPanel = nil
224+
end
225+
226+
leftCode:RunJavascript([[
227+
var value = getEditorValue();
228+
gmod.receiveEditorContent(value);
229+
]])
230+
231+
rightCode:RunJavascript([[
232+
var value = getEditorValue();
233+
gmod.receiveEditorContent(value);
234+
]])
235+
236+
parentPanel.stopCompare = true -- This will be reset when results are displayed
237+
else
238+
if runComparison.Warning and IsValid(runComparison.Warning) then runComparison.Warning:Remove() runComparison.Warning = nil end
239+
runComparison.Warning = Derma_Message("Please wait for the previous comparison to finish", "blobsProfiler - Slow down!", "OK")
240+
end
241+
end
242+
243+
local leftCodeContent
244+
local rightCodeContent
245+
246+
leftCode:AddFunction("gmod", "receiveEditorContent", function(value)
247+
leftCodeContent = value
248+
end)
249+
250+
rightCode:AddFunction("gmod", "receiveEditorContent", function(value)
251+
rightCodeContent = value
252+
253+
if luaState == "Client" then
254+
local numIterations = math.Round(iterationNumSlider:GetValue())
255+
if numIterations > 0 then
256+
local lcMin, lcMax
257+
local rcMin, rcMax -- Why aren't all these on a single line? because, fuck you. Thats why.
258+
259+
-- TODO: Maybe add up the individual times, so the <l/c>c<Max/Min> checks aren't adding to performace (which is likely VERY minor)
260+
local lcStart = SysTime()
261+
for i=1, numIterations do
262+
local ciStart = SysTime()
263+
RunString(leftCodeContent)
264+
local ciTotal = SysTime() - ciStart
265+
266+
if not lcMax or (ciTotal > lcMax) then lcMax = ciTotal end
267+
if not lcMin or (ciTotal < lcMin) then lcMin = ciTotal end
268+
end
269+
local lcTotalTime = SysTime() - lcStart
270+
271+
local rcStart = SysTime()
272+
for i=1, numIterations do
273+
local ciStart = SysTime()
274+
RunString(rightCodeContent)
275+
local ciTotal = SysTime() - ciStart
276+
277+
if not rcMax or (ciTotal > rcMax) then rcMax = ciTotal end
278+
if not rcMin or (ciTotal < rcMin) then rcMin = ciTotal end
279+
end
280+
local rcTotalTime = SysTime() - rcStart
281+
282+
SetupResultsPanel(parentPanel, numIterations, lcTotalTime, lcMin, lcMax, rcTotalTime, rcMin, rcMax)
283+
end
284+
elseif luaState == "Server" then
285+
blobsProfiler.Modules["Lua"].SubModules["Versus"].retrievingData = true
286+
net.Start("blobsProfiler:sendLua_versus")
287+
net.WriteUInt(math.Round(iterationNumSlider:GetValue()) ,20)
288+
net.WriteString(leftCodeContent)
289+
net.WriteString(rightCodeContent)
290+
net.SendToServer()
291+
end
292+
end)
293+
294+
parentPanel.codeContainer = codeContainer
295+
end,
296+
OnOpen = function(luaState, parentPanel)
297+
timer.Simple(0, function()
298+
local width = parentPanel.codeContainer:GetWide()
299+
local dividerWidth = parentPanel.codeContainer:GetDividerWidth() or 8
300+
local halfWidth = (width - dividerWidth) * 0.5
301+
parentPanel.codeContainer:SetLeftWidth(halfWidth)
302+
end)
303+
end
304+
})
305+
136306
net.Receive("blobsProfiler:sendLua", function(l, ply)
137307
if not SERVER or not blobsProfiler.CanAccess(ply, "sendLua", "Server") then return end
138308
local luaRun = net.ReadString()
@@ -141,4 +311,69 @@ net.Receive("blobsProfiler:sendLua", function(l, ply)
141311
blobsProfiler.Log(blobsProfiler.L_LOG, luaRun)
142312

143313
RunString(luaRun)
314+
end)
315+
316+
317+
net.Receive("blobsProfiler:sendLua_versus", function(l, ply)
318+
if not blobsProfiler.CanAccess(ply or LocalPlayer(), "sendLua_versus") then return end
319+
if SERVER then
320+
local numIterations = net.ReadUInt(20)
321+
local luaRunL = net.ReadString()
322+
local luaRunR = net.ReadString()
323+
324+
if numIterations > 0 then
325+
local lcMin, lcMax
326+
local rcMin, rcMax -- Why aren't all these on a single line? because, fuck you. Thats why.
327+
328+
-- TODO: Maybe add up the individual times, so the <l/c>c<Max/Min> checks aren't adding to performace (which is likely VERY minor)
329+
local lcStart = SysTime()
330+
for i=1, numIterations do
331+
local ciStart = SysTime()
332+
RunString(luaRunL)
333+
local ciTotal = SysTime() - ciStart
334+
335+
if not lcMax or (ciTotal > lcMax) then lcMax = ciTotal end
336+
if not lcMin or (ciTotal < lcMin) then lcMin = ciTotal end
337+
end
338+
local lcTotalTime = SysTime() - lcStart
339+
340+
local rcStart = SysTime()
341+
for i=1, numIterations do
342+
local ciStart = SysTime()
343+
RunString(luaRunR)
344+
local ciTotal = SysTime() - ciStart
345+
346+
if not rcMax or (ciTotal > rcMax) then rcMax = ciTotal end
347+
if not rcMin or (ciTotal < rcMin) then rcMin = ciTotal end
348+
end
349+
local rcTotalTime = SysTime() - rcStart
350+
351+
net.Start("blobsProfiler:sendLua_versus")
352+
net.WriteUInt(numIterations, 20)
353+
354+
net.WriteDouble(lcTotalTime)
355+
net.WriteDouble(lcMin)
356+
net.WriteDouble(lcMax)
357+
358+
net.WriteDouble(rcTotalTime)
359+
net.WriteDouble(rcMin)
360+
net.WriteDouble(rcMax)
361+
net.Send(ply)
362+
end
363+
else
364+
blobsProfiler.Modules["Lua"].SubModules["Versus"].retrievingData = false
365+
366+
local numIterations = net.ReadUInt(20)
367+
368+
local lcTotalTime = net.ReadDouble()
369+
local lcMin = net.ReadDouble()
370+
local lcMax = net.ReadDouble()
371+
372+
local rcTotalTime = net.ReadDouble()
373+
local rcMin = net.ReadDouble()
374+
local rcMax = net.ReadDouble()
375+
376+
local parentPanel = blobsProfiler.Modules["Lua"].SubModules["Versus"].ServerTab
377+
SetupResultsPanel(parentPanel, numIterations, lcTotalTime, lcMin, lcMax, rcTotalTime, rcMin, rcMax)
378+
end
144379
end)

0 commit comments

Comments
 (0)