I currently wonder if there is any existing function that requires three arguments (min, max, value), and returns true or false whether value is between min and max, or not ?
Of course, the function is pretty easy to write
function IsBetween (min : float, max : float, value : float) {
if (min <= value value <= max)
return true;
else
return false;
}
but if it already exists, well, writing the function is useless.
that’s not what was asked for. i don’t know about a function that does what you are looking for, but why are you even looking for a function that you have already written?
Five minutes to think about how to answer, but I guess tonyd got us beautifully.
The reason ? Simply curiosity (strangely, I don’t even remember why I asked this question, but well, this knowledge will be useful later, so it is not unworthy) !
I’d guess that the performance variation of n==Clamp, a Between utility function and inlined greater/lessthan tests would be trivial. But one doesn’t have to guess - write loops that do each over 10,000 or 100,000 iterations and time them.
But in normal use, its not going to make any difference. So use whichever one is most readable.
p.s. - I just did such a test. At 100,000 iterations, the Clamp and Between methods are pretty much the same (about 2.4ms) and the inlined greater/less than is a little bit faster at about 2.1ms. Doesn’t seem worth worrying about.
Might be different in java.
Here’s the test code (C#)
private static bool Between(float v, float min, float max)
{
return v > min v < max;
}
void testLoops()
{
System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
timer.Reset();
timer.Start();
for (int i = 0; i < 100000; i++)
{
float v = Random.value;
bool test = Between(v, 1, 100);
}
double betweenTime = timer.Elapsed.TotalMilliseconds;
timer.Reset();
timer.Start();
for (int i = 0; i < 100000; i++)
{
float v = Random.value;
bool test = v == Mathf.Clamp(v, 1, 100);
}
double clampTime = timer.Elapsed.TotalMilliseconds;
timer.Reset();
timer.Start();
for (int i = 0; i < 100000; i++)
{
float v = Random.value;
bool test = v > 1 v < 100;
}
double inlineTime = timer.Elapsed.TotalMilliseconds;
print(string.Format("Between: {0}", betweenTime));
print(string.Format("Clamp: {0}", clampTime));
print(string.Format("Inline: {0}", inlineTime));
}
function IsBetween (value : float, min : float, max : float)
{
return min < value value < max;
}
var betweenTimeStart : double;
var betweenTimeEnd : double;
var betweenDuration : double;
var clampTimeStart : double;
var clampTimeEnd : double;
var clampDuration : double;
var inlineTimeStart : double;
var inlineTimeEnd : double;
var inlineDuration : double;
var i : int;
var v : float;
var test : boolean;
betweenTimeStart = Time.time;
for (i = 0; i < 100000; i++)
{
v = Random.value;
test = IsBetween (v, 1, 100);
}
betweenTimeEnd = Time.time;
betweenDuration = betweenTimeEnd - betweenTimeStart;
clampTimeStart = Time.time;
for (i = 0; i < 100000; i++)
{
v = Random.value;
test = v == Mathf.Clamp (v, 1, 100);
}
clampTimeEnd = Time.time;
clampDuration = clampTimeEnd - clampTimeStart;
inlineTimeStart = Time.time;
for (i = 0; i < 100000; i++)
{
v = Random.value;
test = 1 < v v < 100;
}
inlineTimeEnd = Time.time;
inlineDuration = inlineTimeEnd - inlineTimeStart;
print ("betweenDuration=" + betweenDuration);
print ("clampDuration=" + clampDuration);
print ("inlineDuration=" + inlineDuration);
Its possible that Time.time doesn’t have adequate resolution for this task. You could try increasing the iteration count to 1,000,000. Its also possible that its not asynchronous and so it only updates sometimes and never changes during your test function. That would be easy to detect by comparing its value at the start to its value at the end.
Reasons like that are why I used the Stopwatch - it wraps the Windows high performance timer API functions (though the details of Mono’s linkages are a mystery to me - it worked is all I know) and has resolution in the millionths of a second on most machines. Is there nothing like that for Java?
Unless you are going to be doing this in loops that actually iterate thousands of times per frame, I wouldn’t worry about it at all. If an “IsBetween” function makes your code easier to read, then use that. Or inline the comparisons if you prefer. Or use Clamp.
If you start getting performance problems, then profile the whole system and find where your cycles are burning and optimize there.
Don’t ever assume anything. Sometimes they are not, like the various Lerp functions…it’s faster to write your own functions. (See here.) In this case, the Clamp function is in fact the slowest method…not by a lot, but it is. It’s also awkward compared to a specific Between function.
Yes, you can’t use Time.time like this, since it doesn’t update during the same frame (only between frames). Use Time.realtimeSinceStartup instead.
Well, I wrote my own Lerp functions for different reasons… I needed constant linear movement with no deceleration. I wasn’t getting that with Vector3.Lerp.