nielsie95
2011-06-30 15:15:29
Hey there,
Not so long ago, Wizzup created a thread about structuring the FindColor unit to make it expandable, while maintaining speed. I came with the idea to abstract the comparing function by using a JIT compiler. Today, I put that idea to the test to see if it would be an option. The results aren't astonishing, but are decent to say the least. I didn't use a real JIT compiler, but rather a (compiled) template. This means it will hopefully be easier to port to other platforms.
This is what the template looks like for cts 0:
As you only have to pass a single color, it's faster than other compare functions, while maintaining an abstract interface. With CTS 0 it is a bit slower than inlining the algorithm, but with CTS 1 it is actually faster. I haven't tried it with other algorithms, but I suspect it'll be a faster approach for those too.
Currently, the code is Windows-only, but porting it to Linux shouldn't be hard (hopefully it'll only be a matter of changing the VirtualAlloc to mmap). A downside is that I did not get function calling to work in the copied function, so color converting algorithms will have to be inlined. All in all, it was a nice experiment.
I added the source (including a binary) to this post. I hope it may help some people in the future :)
~Nielsie95
Not so long ago, Wizzup created a thread about structuring the FindColor unit to make it expandable, while maintaining speed. I came with the idea to abstract the comparing function by using a JIT compiler. Today, I put that idea to the test to see if it would be an option. The results aren't astonishing, but are decent to say the least. I didn't use a real JIT compiler, but rather a (compiled) template. This means it will hopefully be easier to port to other platforms.
This is what the template looks like for cts 0:
function func_template(R, G, B: SizeInt): Boolean;
begin
Result :=
(Abs(R - MagicNumber2) <= MagicNumber) and
(Abs(G - MagicNumber3) <= MagicNumber) and
(Abs(B - MagicNumber4) <= MagicNumber);
end;
procedure __next; begin end;
Instead of using 2 colors for input to compare, I use 1 hardcoded set of RGB values. The tolerance is also hardcoded (notice the MagicNumbers). To create a runtime compare function for a specified color and tolerance, I just "copy" the function and change the MagicNumbers to the real RGB and tolerance values. This will result in a function in memory which will always compare to a certain color using a certain tolerance.As you only have to pass a single color, it's faster than other compare functions, while maintaining an abstract interface. With CTS 0 it is a bit slower than inlining the algorithm, but with CTS 1 it is actually faster. I haven't tried it with other algorithms, but I suspect it'll be a faster approach for those too.
Currently, the code is Windows-only, but porting it to Linux shouldn't be hard (hopefully it'll only be a matter of changing the VirtualAlloc to mmap). A downside is that I did not get function calling to work in the copied function, so color converting algorithms will have to be inlined. All in all, it was a nice experiment.
I added the source (including a binary) to this post. I hope it may help some people in the future :)
~Nielsie95