你如何创建一个大型阵列?

时间:2016-06-06 17:24:11

标签: arrays f# c#-to-f# gcallowverylargeobjects

给出

// r is a System.Data.IDataRecord
var blob = new byte[(r.GetBytes(0, 0, null, 0, int.MaxValue))];
r.GetBytes(0, 0, blob, 0, blob.Length);

r.GetBytes(...)返回Int64 由于Array.zeroCreateArray.init采用Int32,如何创建一个可能大于Int32.MaxValue的空数组?

2 个答案:

答案 0 :(得分:6)

In .NET 4.5 and newer, the gcAllowVeryLargeObjects configuration element可以创建大于2GB的单个对象,但即使这样也不会改变数量上的硬限制数组中的元素。引用备注部分:

  

数组中的最大元素数是UInt32.MaxValue。

     

对于字节数组和单字节结构数组,任何单个维度的最大索引为2,147,483,591(0x7FFFFFC7),其他类型为2,146,435,071(0X7FEFFFFF)。

我不完全确定为什么UInt32而不是Int32(你可以创建最小索引为Int32.MinValue的数组,但是我&# 39;我不确定你是否能够做很多事情: - ))。

但是,使用gcAllowVeryLargeObjects参数,您可以通过创建包含多个值的结构数组来创建非常大的数组 - 这将分配超过2GB的连续内存块:

[<Struct>]
type Quadruple<'T>(v1:'T, v2:'T, v3:'T, v4:'T) = 
  member x.V1 = v1
  member x.V2 = v2
  member x.V3 = v3
  member x.V4 = v4

let qa : Quadruple<byte>[] = Array.zeroCreate 10 

我不认为这是特别实用的,但这是一种可能性。实际上,将数据拆分为数组数组似乎更容易。当单个数组大约为2GB时,一个级别的间接可能不会导致过多的开销。

答案 1 :(得分:3)

你做不到。 .NET上一维数组的最大长度为System.Int32.MaxValue。当值大于此限制时,您的C#代码会引发OverflowException。等效的F#代码是:

let blob =         
    let length = r.GetBytes(0, 0, null, 0, Int32.MaxValue)
    if length > int64(Int32.MaxValue) then
        raise (OverflowException())
    else
        Array.zeroCreate<byte>(int32(length))
相关问题