Forum > FPC development
[SOLVED]Improvement of packages/fcl-image/src/fpcanvas.inc TFPCustomCanvas.Erase
lagprogramming:
packages/fcl-image/src/fpcanvas.inc contains the following procedure:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TFPCustomCanvas.Erase;var x,y:Integer;begin for x:=0 to Width-1 do for y:=0 to Height-1 do Colors[x,y]:=colTransparent;end; The following procedure should be faster. I've switched the for loops.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TFPCustomCanvas.Erase;var x,y:Integer;begin for y:=0 to Height-1 do for x:=0 to Width-1 do Colors[x,y]:=colTransparent;end;
Чебурашка:
--- Quote from: lagprogramming on March 23, 2023, 09:53:06 am ---packages/fcl-image/src/fpcanvas.inc contains the following procedure:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TFPCustomCanvas.Erase;var x,y:Integer;begin for x:=0 to Width-1 do for y:=0 to Height-1 do Colors[x,y]:=colTransparent;end; The following procedure should be faster. I've switched the for loops.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TFPCustomCanvas.Erase;var x,y:Integer;begin for y:=0 to Height-1 do for x:=0 to Width-1 do Colors[x,y]:=colTransparent;end;
--- End quote ---
I am curious to know what is the difference in terms of execution time, could you please explain/demonstrate?
lagprogramming:
--- Quote from: Чебурашка on March 23, 2023, 10:47:35 am ---I am curious to know what is the difference in terms of execution time, could you please explain/demonstrate?
--- End quote ---
It's a matter of CPU cache usage.
Original code "erases"(which in fact consists in writing data) all the lines(rows) of the canvas simultaneously. This means that the CPU will try to simultaneously cache writes for many lines, no more than the height of the canvas.
New CPUs have huge caches and good mechanisms of managing it, but old CPUs are not that good. Those old CPUs will run the proposed code faster than the original code because the data writes are leaner, more fluent.
Also, there are CPUs that write data forward significantly faster than writing it backward. This is another example of CPU cache usage.
Чебурашка:
--- Quote from: lagprogramming on March 23, 2023, 03:12:57 pm ---
--- Quote from: Чебурашка on March 23, 2023, 10:47:35 am ---I am curious to know what is the difference in terms of execution time, could you please explain/demonstrate?
--- End quote ---
It's a matter of CPU cache usage.
Original code "erases"(which in fact consists in writing data) all the lines(rows) of the canvas simultaneously. This means that the CPU will try to simultaneously cache writes for many lines, no more than the height of the canvas.
New CPUs have huge caches and good mechanisms of managing it, but old CPUs are not that good. Those old CPUs will run the proposed code faster than the original code because the data writes are leaner, more fluent.
Also, there are CPUs that write data forward significantly faster than writing it backward. This is another example of CPU cache usage.
--- End quote ---
Very interesting, thank you.
wp:
Here's a test project which measures the execution time for both methods. There's a 40% speed gain when y is in the outer loop (taking the case of x in the outer loop as a reference). Tested on a 10,000 x 10,000 pixel image.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program project1; uses SysUtils, fpImage, fpCanvas, fpImgCanv; const WIDTH = 10*1000; HEIGHT = 10*1000;var t: TDateTime; img: TFPCustomImage; cnv: TFPCustomCanvas; i, x, y: Integer;begin for i := 1 to 5 do begin WriteLn('Run #', i); img := TFPMemoryImage.Create(WIDTH, HEIGHT); try cnv := TFPImageCanvas.Create(img); try Write(' outer loop x...: '); t := Now; for x:=0 to img.Width-1 do for y:=0 to img.Height-1 do cnv.Colors[x,y] := colTransparent; t := Now-t; WriteLn(FormatDateTime('s.zzz" seconds"', t)); Write(' outer loop y...: '); t := Now; for y:=0 to img.Height-1 do for x:=0 to img.Width-1 do cnv.Colors[x,y] := colTransparent; t := Now-t; WriteLn(FormatDateTime('s.zzz" seconds"', t)); finally cnv.Free; end; finally img.Free; end; WriteLn; end; Write('Done. Press ENTER to quit...'); ReadLn;end.
Post a patch to the FPC bug tracker, I doubt whether the developers taking care of graphics read this here.
Navigation
[0] Message Index
[#] Next page