local found_bitser, bitser = pcall(require, 'bitser') local found_binser, binser = pcall(require, 'binser') local found_ser, ser = pcall(require, 'ser') local found_serpent, serpent = pcall(require, 'serpent') local found_smallfolk, smallfolk = pcall(require, 'smallfolk') local found_msgpack, msgpack = pcall(require, 'MessagePack') local cases local selected_case = 1 local sers = {} local desers = {} if found_bitser then sers.bitser = bitser.dumps desers.bitser = bitser.loads bitser.reserveBuffer(1024 * 1024) end if found_binser then sers.binser = binser.s desers.binser = binser.d end if found_ser then sers.ser = ser desers.ser = loadstring end if found_serpent then sers.serpent = serpent.dump desers.serpent = loadstring end if found_smallfolk then sers.smallfolk = smallfolk.dumps desers.smallfolk = smallfolk.loads end if found_msgpack then sers.msgpack = msgpack.pack desers.msgpack = msgpack.unpack end local view_absolute = true local resultname = "serialisation time in seconds" function love.load() cases = love.filesystem.getDirectoryItems("cases") state = 'select_case' love.graphics.setBackgroundColor(1, 230/256, 220/256) love.graphics.setColor(40/256, 30/256, 0/256) love.window.setTitle("Select a benchmark testcase") end function love.keypressed(key) if state == 'select_case' then if key == 'up' then selected_case = (selected_case - 2) % #cases + 1 elseif key == 'down' then selected_case = selected_case % #cases + 1 elseif key == 'return' then state = 'calculate_results' love.window.setTitle("Running benchmark...") end elseif state == 'results' then if key == 'r' then view_absolute = not view_absolute elseif key == 'right' then if results == results_ser then results = results_deser resultname = "deserialisation time in seconds" elseif results == results_deser then results = results_size resultname = "size of output in bytes" elseif results == results_size then results = results_ser resultname = "serialisation time in seconds" end elseif key == 'left' then if results == results_ser then results = results_size resultname = "size of output in bytes" elseif results == results_deser then results = results_ser resultname = "serialisation time in seconds" elseif results == results_size then results = results_deser resultname = "deserialisation time in seconds" end elseif key == 'escape' then state = 'select_case' love.window.setTitle("Select a benchmark testcase") end end end function love.draw() if state == 'select_case' then for i, case in ipairs(cases) do love.graphics.print(case, selected_case == i and 60 or 20, i * 20) end local i = 2 love.graphics.print('serialisation libraries installed:', 200, 20) for sername in pairs(sers) do love.graphics.print(sername, 200, i * 20) i = i + 1 end elseif state == 'calculate_results' then love.graphics.print("Running benchmark...", 20, 20) love.graphics.print("This may take a while", 20, 40) state = 'calculate_results_2' elseif state == 'calculate_results_2' then local data, iters, tries = love.filesystem.load("cases/" .. cases[selected_case])() results_ser = {} results = results_ser resultname = "serialisation time in seconds" results_size = {} results_deser = {} errors = {} for sername, serializer in pairs(sers) do results_ser[sername] = math.huge results_deser[sername] = math.huge end local outputs = {} for try = 1, tries do for sername, serializer in pairs(sers) do local output local success, diff = pcall(function() local t = os.clock() for i = 1, iters do output = serializer(data) end return os.clock() - t end) if not success and not errors[sername] then errors[sername] = diff elseif success and diff < results_ser[sername] then results_ser[sername] = diff end if try == 1 then outputs[sername] = output results_size[sername] = output and #output or math.huge end end end for try = 1, tries do for sername, deserializer in pairs(desers) do local input = outputs[sername] local success, diff = pcall(function() local t = os.clock() for i = 1, iters / 10 do deserializer(input) end return os.clock() - t end) if not success and not errors[sername] then errors[sername] = diff elseif success and diff < results_deser[sername] then results_deser[sername] = diff end end end state = 'results' love.window.setTitle("Results for " .. cases[selected_case]) elseif state == 'results' then local results_min = math.huge local results_max = -math.huge for sername, result in pairs(results) do if result < results_min then results_min = result end if result > results_max and result < math.huge then results_max = result end end if view_absolute then results_min = 0 end local i = 1 for sername, result in pairs(results) do love.graphics.print(sername, 20, i * 20) if result == math.huge then love.graphics.setColor(220/256, 30/256, 0) love.graphics.rectangle('fill', 100, i * 20, 780 - 100, 18) love.graphics.setColor(40/256, 30/256, 0) love.graphics.print(errors[sername], 102, i * 20 + 2) else love.graphics.rectangle('fill', 100, i * 20, (780 - 100) * (result - results_min) / (results_max - results_min), 18) end i = i + 1 end love.graphics.print(results_min, 100, i * 20) love.graphics.print(results_max, 780 - love.graphics.getFont():getWidth(results_max), i * 20) love.graphics.print(resultname .." (smaller is better; try left, right, R, escape)", 100, i * 20 + 20) end end