From b9361d54c6781b736064f4957febcf39b569bd39 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 29 Mar 2014 22:52:04 +0100 Subject: [PATCH] gears.color: Add a pattern cache This makes gears.color() cache patterns in a weak table and returns that cached pattern when we get called with the same argument again. To benchmark this change, the following code was used: local time = require("socket").gettime function benchmark(func) local begin = time() local iter = 0 while time() - begin < 1 do func() iter = iter + 1 end return iter end for _, arg in pairs({ "#00aa00", "solid:#00aa00", "radial:50,50,10:55,55,30:0,#ff0000:0.5,#00ff00:1,#0000ff", "linear:1,2:3,4:0,#000000:1,#ffffff", "png:/home/psychon/Wallpaper/Bars.png", { type = "solid", color = "#00aa00" }, { type = "radial", from = { 50, 50, 10 }, to = { 55, 55, 30 }, stops = { { 0, "#ff0000" }, { 0.5, "#00ff00" }, { 1, "#0000ff" } } }, { type = "linear", from = { 1, 2 }, to = { 3, 4 }, stops = { { 0, "#000000" }, { 1, "#ffffff" } } }, { type = "png", file = "/home/psychon/Wallpaper/Bars.png" }, }) do collectgarbage("collect") print(benchmark(function() gears.color.create_pattern(arg) end), arg) end Before this change (larger numbers are better, this measures how many times we can create the given pattern per second): 29525 #00aa00 29344 solid:#00aa00 3446 radial:50,50,10:55,55,30:0,#ff0000:0.5,#00ff00:1,#0000ff 4845 linear:1,2:3,4:0,#000000:1,#ffffff 32855 png:/home/psychon/Wallpaper/Bars.png 29883 table: 0x1bb67e0 3868 table: 0x1bb6830 5339 table: 0x1bb6c60 32772 table: 0x1bb6fe0 After this change: 126188 #00aa00 125962 solid:#00aa00 125125 radial:50,50,10:55,55,30:0,#ff0000:0.5,#00ff00:1,#0000ff 125213 linear:1,2:3,4:0,#000000:1,#ffffff 113659 png:/home/psychon/Wallpaper/Bars.png 125586 table: 0x1232680 125249 table: 0x12326d0 125468 table: 0x1232b00 113711 table: 0x1232e80 As you see, this makes some cases about 35 times faster (although I have to admit that something like this can be expected from such a synthetic benchmark). Signed-off-by: Uli Schlachter --- lib/gears/color.lua.in | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/gears/color.lua.in b/lib/gears/color.lua.in index d3c30135c..115babb42 100644 --- a/lib/gears/color.lua.in +++ b/lib/gears/color.lua.in @@ -16,6 +16,7 @@ local cairo = require("lgi").cairo local surface = require("gears.surface") local color = { mt = {} } +local pattern_cache = setmetatable({}, { __mode = 'v' }) --- Parse a HTML-color. -- This function can parse colors like #rrggbb and #rrggbbaa. @@ -186,20 +187,28 @@ function color.create_pattern(col) if cairo.Pattern:is_type_of(col) then return col end + local result = col and pattern_cache[col] + if result then + return result + end if type(col) == "string" then local t = string.match(col, "[^:]+") if color.types[t] then local pos = string.len(t) local arg = string.sub(col, pos + 2) - return color.types[t](arg) + result = color.types[t](arg) end elseif type(col) == "table" then local t = col.type if color.types[t] then - return color.types[t](col) + result = color.types[t](col) end end - return color.create_solid_pattern(col) + if not result then + result = color.create_solid_pattern(col) + end + pattern_cache[col] = result + return result end --- Check if a pattern is opaque.