I am trying to devise a way (.NET 4.5.2) to very quickly determine if an int falls within a numeric range. Ranges do not overlap. Speed is the #1 priority for this all-in-memory operation. The below code works fine, but the actual system will have 500,000 rows sourced from a DB and I am concerned that looking for range hits in the middle of the array will incur a performance penalty. Once data is read from the DB it stays in-memory and is used as reference data in a web application.
All ideas appreciated. And thanks to https://stackoverflow.com/a/5612589/139618 for the Filter method.
// Running console app correctly shows "2288779".
static void Main( string[] args )
{
int[,] intervals = new int[3, 3];
intervals[0, 0] = 200;
intervals[0, 1] = 250;
intervals[0, 2] = 1121214;
intervals[1, 0] = 300;
intervals[1, 1] = 350;
intervals[1, 2] = 2288779;
intervals[2, 0] = 400;
intervals[2, 1] = 450;
intervals[2, 2] = 3300004;
var seekIntA = 336;
var result = Filter(intervals, u => u[0] <= seekIntA && u[1] >= seekIntA).FirstOrDefault();
if (null != result)
{
Console.WriteLine(result[2]);
}
else
{
Console.WriteLine("null");
}
}
public static IEnumerable<T[]> Filter<T>( T[,] source , Func<T[] , bool> predicate )
{
for ( int i = 0 ; i < source.GetLength( 0 ) ; ++i )
{
T[] values = new T[source.GetLength( 1 )];
for ( int j = 0 ; j < values.Length ; ++j )
{
values[j] = source[i , j];
}
if ( predicate( values ) )
{
yield return values;
}
}
}
I am open to scrapping the array idea altogether and using any other collection (lower case intentional) type to store/seek the ranges.
Thanks.
{rangeBoundary, Data1, Data2}or somehow "range" is defined by more than 2 values? (If it is just one-dimensional search than binary search is the fastest solution for generic case).class/structwith 2 values (i.e. as shown in Assafss answer) would be way more readable and self-documenting while still easy to convert back to arrays if you really need it.