【发布时间】:2014-10-27 11:13:46
【问题描述】:
我正在尝试设计一种方法 (.NET 4.5.2) 来非常快速地确定 int 是否在数字范围内。范围不重叠。速度是这种全内存操作的第一要务。 下面的代码工作正常,但实际系统将有 500,000 行来自数据库,我担心在数组中间查找范围命中会导致性能损失。从数据库中读取数据后,它会保留在内存中并用作 Web 应用程序中的参考数据。
感谢所有想法。感谢 https://stackoverflow.com/a/5612589/139618 提供的 Filter 方法。
// 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;
}
}
}
我愿意完全放弃数组的想法,并使用任何其他集合(有意小写)类型来存储/查找范围。
谢谢。
【问题讨论】:
-
当你有一个看起来像 n*3 的数组时,不确定你是什么意思“在数字范围内”... 3 更像
{rangeBoundary, Data1, Data2}或者不知何故“范围”被定义为超过2个值? (如果只是一维搜索,那么对于一般情况,二分搜索是最快的解决方案)。 -
@Alexi,区间 [0,0] 包含一个范围的下限,区间 [0,1] 包含上限,区间 [0,2] 包含任何范围的结果值包含在包含范围内的数字。
-
我明白了。旁注:您为什么选择使用数组而不是公共示例代码?
class/struct具有 2 个值(即如 Assafss 答案中所示)将更具可读性和自我记录性,同时如果您确实需要它仍然很容易转换回数组。 -
可能过度思考使用原始类型会比类(甚至是结构)更快且内存效率更高的风险。我需要它尽可能快并且使用最少的内存,因为它会在负载下被非常非常多的同时请求读取。
标签: c# arrays performance linq multidimensional-array