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 <psychon@znc.in>
This commit is contained in:
parent
79ad0d3e6e
commit
b9361d54c6
|
@ -16,6 +16,7 @@ local cairo = require("lgi").cairo
|
||||||
local surface = require("gears.surface")
|
local surface = require("gears.surface")
|
||||||
|
|
||||||
local color = { mt = {} }
|
local color = { mt = {} }
|
||||||
|
local pattern_cache = setmetatable({}, { __mode = 'v' })
|
||||||
|
|
||||||
--- Parse a HTML-color.
|
--- Parse a HTML-color.
|
||||||
-- This function can parse colors like #rrggbb and #rrggbbaa.
|
-- 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
|
if cairo.Pattern:is_type_of(col) then
|
||||||
return col
|
return col
|
||||||
end
|
end
|
||||||
|
local result = col and pattern_cache[col]
|
||||||
|
if result then
|
||||||
|
return result
|
||||||
|
end
|
||||||
if type(col) == "string" then
|
if type(col) == "string" then
|
||||||
local t = string.match(col, "[^:]+")
|
local t = string.match(col, "[^:]+")
|
||||||
if color.types[t] then
|
if color.types[t] then
|
||||||
local pos = string.len(t)
|
local pos = string.len(t)
|
||||||
local arg = string.sub(col, pos + 2)
|
local arg = string.sub(col, pos + 2)
|
||||||
return color.types[t](arg)
|
result = color.types[t](arg)
|
||||||
end
|
end
|
||||||
elseif type(col) == "table" then
|
elseif type(col) == "table" then
|
||||||
local t = col.type
|
local t = col.type
|
||||||
if color.types[t] then
|
if color.types[t] then
|
||||||
return color.types[t](col)
|
result = color.types[t](col)
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
--- Check if a pattern is opaque.
|
--- Check if a pattern is opaque.
|
||||||
|
|
Loading…
Reference in New Issue