Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / Optimize this "if" routine?

Author
Message
Ashingda 27
18
Years of Service
User Offline
Joined: 15th Feb 2008
Location:
Posted: 16th Jul 2011 05:53
I am running through a lot of this bit of code here and was wondering if it can be optimized. This is used for my color function to find which of the RGB values are the current high and lows.


Hodgey
16
Years of Service
User Offline
Joined: 10th Oct 2009
Location: Australia
Posted: 16th Jul 2011 06:33
I can't think of anything but if you're worried about it chewing up performance you could always wrap some time checking around it. Get it to check every 20 milliseconds or something like that.

BatVink
Moderator
23
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 16th Jul 2011 12:57
Using Matrix Utils:

High = MAX( r, g)
High = MAX(High, b)
Low = MIN( r, g)
Low = MIN(Low, b)

Green Gandalf
VIP Member
21
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 16th Jul 2011 12:58
There's no point in doing both



and



If the first test passes there's no point doing the second one. Perhaps do this instead?



and likewise for the other two colour components.
Hodgey
16
Years of Service
User Offline
Joined: 10th Oct 2009
Location: Australia
Posted: 16th Jul 2011 14:51
@ Green Gandalf
I missed that one. I will admit, on the outside it looks like the same amount of checking.

Sasuke
20
Years of Service
User Offline
Joined: 2nd Dec 2005
Location: Milton Keynes UK
Posted: 16th Jul 2011 16:59 Edited at: 16th Jul 2011 17:09
I wonder if this is over kill. I was thinking how you'd be able to work out upper and lower limit and amend the value in one calculation. So the result:

Value = ( Lower*(Value<Lower) || Upper*(Value>Upper) ) + Value * ( 1-( Value<Lower || Value>Upper ) )

You could turn that into a function, then again, we already have IanM's plugin for this.

Ashingda 27
18
Years of Service
User Offline
Joined: 15th Feb 2008
Location:
Posted: 16th Jul 2011 21:18
@Green Gandalf
I gave that a try, it gave more speed but miss some needed checks and the color don't turn out right sometimes.

@Sasuke
I'm not really understanding that

@BatVink
I notice that calling a function in dbpro is slower than just using the codes directly. But I did find something that works based off what you showed me. This cuts out 2 if checks.


Then later turned to this, adding the multiple if/else Green Gandalf suggested which also cuts out 1 extra if check.


Thank you everyone this helped out a lot!

Green Gandalf
VIP Member
21
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 16th Jul 2011 22:05
Quote: "I gave that a try, it gave more speed but miss some needed checks and the color don't turn out right sometimes."


Show me your code. It should have worked if implemented correctly.

I'm sure it's possible to do better than my solution though.
Ashingda 27
18
Years of Service
User Offline
Joined: 15th Feb 2008
Location:
Posted: 16th Jul 2011 22:37
This is what was happening.


Green Gandalf
VIP Member
21
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 16th Jul 2011 22:58
Well, as I said, you need to implement it correctly.

Looks like you forgot to replace one of the r's with a b.

Look again:



We all make that kind of "cut and paste then edit" error. Looks like an annoying fact of life.

Sounds like you've got some good ideas to work with though.
Ashingda 27
18
Years of Service
User Offline
Joined: 15th Feb 2008
Location:
Posted: 16th Jul 2011 23:06
That was typed out from memory, but the process still would come out the same. If the Low is checked then the High never gets check.

If I have r=230, g=220, b=210 when it process the Low value starts at 255, it will check r for Low (skips the High check), then check g for Low (Skip High check again) and check b for Low (Again skiping the High Check).

So depending on what values the color has, it may or may not check for either the High or Low values properly.

Sasuke
20
Years of Service
User Offline
Joined: 2nd Dec 2005
Location: Milton Keynes UK
Posted: 16th Jul 2011 23:29
Quote: "I'm not really understanding that"


Whoops, should of wrote 'Side Note' cause it kind of doesn't go with this thread.
Hodgey
16
Years of Service
User Offline
Joined: 10th Oct 2009
Location: Australia
Posted: 16th Jul 2011 23:54
Quote: " If the Low is checked then the High never gets check.
"

Quote: "If I have r=230, g=220, b=210 when it process the Low value starts at 255, it will check r for Low (skips the High check), then check g for Low (Skip High check again) and check b for Low (Again skiping the High Check)."

So with that logic, high and low can have the same values?

Green Gandalf
VIP Member
21
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 17th Jul 2011 00:08
Quote: "If the Low is checked then the High never gets check."


Quite right.

I was thinking that the initial values of High and Low were realistic and satisfied Low <= High.

Just use the following instead (which is also much simpler ):



Sorry for the confusion.
Ashingda 27
18
Years of Service
User Offline
Joined: 15th Feb 2008
Location:
Posted: 17th Jul 2011 00:10
Yes what if the color is gray r=100 g=100 b=100 or a single color like red, r=255 g=0 b=0 where 2 values are the same. I need to check a high and a low value for the function to get the right color.

Ashingda 27
18
Years of Service
User Offline
Joined: 15th Feb 2008
Location:
Posted: 17th Jul 2011 00:18
The slowest process in this routine is when a variable is assigned a value (Low=r). The less of that happening the faster it goes.

Green Gandalf
VIP Member
21
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 17th Jul 2011 00:29
Quote: "Yes what if the color is gray r=100 g=100 b=100 or a single color like red, r=255 g=0 b=0 where 2 values are the same. I need to check a high and a low value for the function to get the right color."


The first case will return 100 for both, the second will return 255 for High and 0 for Low. What do you think happens?
Sasuke
20
Years of Service
User Offline
Joined: 2nd Dec 2005
Location: Milton Keynes UK
Posted: 17th Jul 2011 00:44
I wonder (again), you could do:

For Higher:
High = (R + G + B * 2 + abs(R - G) + abs(R + G - B * 2 + abs(R - G))) / 4;

Gimme a sec for lower...
Libervurto
20
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 17th Jul 2011 02:32
I don't know how fast this is, just an idea I had.


WLGfx
18
Years of Service
User Offline
Joined: 1st Nov 2007
Location: NW United Kingdom
Posted: 17th Jul 2011 02:39
@Sasuke - Using a single 'IF' statement will cut out the processing a lot of calculations that aren't necessary if that condition is true. Helpful if there's a lot of processing needed doing during that time. Some programmers will nest 'IF' statements to speed up portions of their code. (It adds more text to the source file but speeds up the programs end result)

Warning! May contain Nuts!
Hodgey
16
Years of Service
User Offline
Joined: 10th Oct 2009
Location: Australia
Posted: 17th Jul 2011 02:40 Edited at: 17th Jul 2011 02:42
@ Obese87: I think we then go back to this problem:
Quote: "Yes what if the color is gray r=100 g=100 b=100 or a single color like red, r=255 g=0 b=0 where 2 values are the same. I need to check a high and a low value for the function to get the right color."

when two or more of the values are equal.

Libervurto
20
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 17th Jul 2011 02:44
@Sasuke
Addition is quicker than multiplication so
High = (R + G + B + B + abs(R - G) + abs(R + G - B + B + abs(R - G))) / 4
Will be a bit faster than
High = (R + G + B * 2 + abs(R - G) + abs(R + G - B * 2 + abs(R - G))) / 4

You use ABS() three times, that might slow it down a bit, try working out how to do it without ABS() or see if you can cut down the number of times you use the function.

WLGfx
18
Years of Service
User Offline
Joined: 1st Nov 2007
Location: NW United Kingdom
Posted: 17th Jul 2011 02:52
@Obese87 - Your first snippet was more efficient for speed and optimisation than the last one (referenced to Sasukes).

Also on the same lines as Green Gandalfs.

It looked like someone was missing the point.

Warning! May contain Nuts!
Libervurto
20
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 17th Jul 2011 03:00
@Hodgey
If two or more values are equal my conditions will just go down the false branch instead of the true branch. Both HIGH and LOW get assigned no matter what the outcome of the conditions.

Hodgey
16
Years of Service
User Offline
Joined: 10th Oct 2009
Location: Australia
Posted: 17th Jul 2011 03:18
Quote: "If two or more values are equal my conditions will just go down the false branch instead of the true branch. Both HIGH and LOW get assigned no matter what the outcome of the conditions.
"

Yep my bad, sorry Obese87

Kevin Picone
23
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Australia
Posted: 17th Jul 2011 04:40 Edited at: 17th Jul 2011 09:28
Ashingda 27,

Only had a bit of look at the snippet and seems the first comparisons to low/high are redundant, so Low and HIGH could be set the either R,G or B initially. Beyond that, we're just comparing the others to that point.





In speed terms.. i dunno..shuffle #2 has less operations so it should be quicker, but that doesn't necessarily make it so, as such things are often compiler biased. It's temping to go the boolean expression approach also (as others have already shown), but I have my doubts how well that'd work in Dbpro.

If this type logic is going to be something that's to be called heavily, then it'd best to in line the logic into the main routine, rather than wrap it up into a function.

Ashingda 27
18
Years of Service
User Offline
Joined: 15th Feb 2008
Location:
Posted: 17th Jul 2011 09:15
@Kevin Picone
Wow that shuffle#2 would work out very well indeed!

Quote: "it'd best to in line the logic into the routine, rather than wrap such logic up into a function"

True it's just that I'm calling it 4 separate times from another function and the function this is taken from is quite large. I will eventually put them together to squeeze out a bit more speed.

Thanks everyone, appreciate it

Green Gandalf
VIP Member
21
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 17th Jul 2011 13:05
@Kevine Picone

In your "Shuffle #1" did you mean this (as in my last snippet)



rather than this





I like the look of your Shuffle #2 though.
Kevin Picone
23
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Australia
Posted: 18th Jul 2011 04:49
Quote: "In your "Shuffle #1" did you mean this (as in my last snippet)"


Nope.

Grog Grueslayer
Valued Member
21
Years of Service
User Offline
Joined: 30th May 2005
Playing: Green Hell
Posted: 18th Jul 2011 08:15
Like BatVink I think IanMs great commands are the way to go. If you put the rgb colors in an array you can use SORT ARRAY and instantly know the low and high colors without any IF/THEN statements.



Green Gandalf
VIP Member
21
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 18th Jul 2011 12:01
Quote: "Nope."


Then I'm missing the point of your code. Perhaps you could explain why "b" is handled differently from "g"? My brain is not as young as it was.

Quote: "Like BatVink I think IanMs great commands are the way to go. If you put the rgb colors in an array you can use SORT ARRAY and instantly know the low and high colors without any IF/THEN statements."


Sounds promising - but might the extra assignments slow it down?
IanM
Retired Moderator
23
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 18th Jul 2011 15:30
Kevin's 'Shuffle #2' would be my choice if sheer speed was the target and was getting desperate for optimisations. Otherwise, I'd use MIN/MAX from my functions, as it wouldn't be too much slower and is a lot more readable. (That 'desperate' was a hint BTW. First rule - 'don't', second rule for experts - 'measure first and prove it's needed').

The only time I'd consider using the SORT ARRAY command is if I was taking 100's of values and picking low/high from the whole set - the startup time for sorting is simply too heavy for a smaller number of values, although I'm not sure where the break-even point would be.

Does anyone regularly use min/max on 3 or more values simultaneously?

Grog Grueslayer
Valued Member
21
Years of Service
User Offline
Joined: 30th May 2005
Playing: Green Hell
Posted: 18th Jul 2011 18:12
Quote: "the startup time for sorting is simply too heavy for a smaller number of values, although I'm not sure where the break-even point would be."


I figured it would be slow too but it is a cool looking way to do it.

Quote: "Does anyone regularly use min/max on 3 or more values simultaneously?"


This hints of an update to MIN/MAX.

I don't usually use them but it would be nice to be able to do more than just 2 numbers at a time.

Sasuke
20
Years of Service
User Offline
Joined: 2nd Dec 2005
Location: Milton Keynes UK
Posted: 18th Jul 2011 18:51 Edited at: 19th Jul 2011 01:54
OBese87, This would give you an error:
High = (R + G + B + B + abs(R - G) + abs(R + G - B + B + abs(R - G))) / 4
You'd need to do this:
High = (R + G + (B + B) + abs(R - G) + abs(R + G - (B + B) + abs(R - G))) / 4

As of speed, I know it's not the fastest method, I just wanted to work it out in one calculation. I guess you could speed it up by splitting it up:

a = R+G
b = B+B
c = R-G
if c < 0 then c = -c
d = a - b + c
if d < 0 then d = -d
High = (a + b + c + d) / 4

But IF's are way faster.
Jimpo
21
Years of Service
User Offline
Joined: 9th Apr 2005
Location:
Posted: 18th Jul 2011 21:44 Edited at: 18th Jul 2011 21:47

3 conditionals and 2 or 3 assignments

Though I agree with IanM, does this really need to be that optimized?

Green Gandalf
VIP Member
21
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 19th Jul 2011 00:57


That's always two tests when you might only need one - same problem as in the original poster's code (and KP's Shuffle #1).

Quote: "Though I agree with IanM, does this really need to be that optimized?"


Who knows? Depends entirely on how many times you need to do it.

Actually this is one of those cases where the simplicity of the code posted by Ashingda 27 probably outweighs the advantages of the other methods - unless he's processing screen images in real time in which case you might need the extra speed.
Ashingda 27
18
Years of Service
User Offline
Joined: 15th Feb 2008
Location:
Posted: 19th Jul 2011 01:04 Edited at: 19th Jul 2011 01:07
Quote: "Though I agree with IanM, does this really need to be that optimized?"

I'm using this to swap the colors of my character sprite sheet. My test shows the speed it takes to put all the different images together (Head,Body,Hair,Weapon,Shield) to be timed at about 26 when I add the color swap function it ends up at 70.

Edit
The original codes I posted up for help tested at about 80 so already with help from this post I shaved off 10 points. The color I'm modifying are for the characters you see on my sig below.

Jimpo
21
Years of Service
User Offline
Joined: 9th Apr 2005
Location:
Posted: 19th Jul 2011 01:48
Quote: "
That's always two tests when you might only need one - same problem as in the original poster's code (and KP's Shuffle #1)."

Good point! And a simple change too!


So the best case will only have 2 conditionals and 2 assignments.

Green Gandalf
VIP Member
21
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 19th Jul 2011 13:53
Yes.
IanM
Retired Moderator
23
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 19th Jul 2011 15:15
@Ashingda 27,
If it's image processing you are doing, then surely you should be using something like ImageKit to combine images, with a shader to carry out your colour change.

Basically, as is nearly always the case, it looks like you are optimising in the wrong place.

Ashingda 27
18
Years of Service
User Offline
Joined: 15th Feb 2008
Location:
Posted: 20th Jul 2011 01:56
@IanM
I am using the Advanced Sprites plugin and have a customized check for combining the images. I can't use any other plugins or shaders to do a color change because the sprites uses a color key system where all hair are green, body are blue, armor are magenta and so on. Colors are also being modified similar to the effects of photoshop, using a Hue rotation, Brightness, Saturation and contrast level, so it's not just simply diffusing color values.


This "if" routine was part of the many "if" checks that slowed it down. I've made some adjustments and managed to drop my time from 70 to 45 now I am very pleased with the result so far.


I remember testing out ImageKit and it didn't give me a very good result in terms of speed compared to Advanced Sprites and didn't allow my the bit of lower level access to the pixels. I may have not used it to it's potential, I will however test it out again just to make sure.

Login to post a reply

Server time is: 2026-07-10 20:57:56
Your offset time is: 2026-07-10 20:57:56