Skip to content

Instantly share code, notes, and snippets.

@jackmott
Last active August 19, 2016 21:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jackmott/c75f7e871ded1a787810161be2384148 to your computer and use it in GitHub Desktop.
Save jackmott/c75f7e871ded1a787810161be2384148 to your computer and use it in GitHub Desktop.
experimental filter
let filterUltra f (array : 'T[]) =
let inline computeChunk (x:float32) =
int((float32)array.Length*x)
let chunkProgression =
match sizeof<'T> * array.Length with
| x when x < 4096 -> [|array.Length|]
| x when x < 65536 -> [|computeChunk 0.25f;computeChunk 0.76f|]
| x when x < 262144 -> [|computeChunk 0.14f;computeChunk 0.29f;computeChunk 0.58f|]
| _ -> [|computeChunk 0.07f;computeChunk 0.13f;computeChunk 0.27f;computeChunk 0.54f|] //4
let chunkCount = chunkProgression.Length
let chunks = Array.create chunkCount empty
let mutable chunkIndex = 0
let mutable totalSize = 0
let mutable i = 0
let mutable count = 0
while i < array.Length && chunkIndex < chunkCount do
let chunkSize = chunkProgression.[chunkIndex]
chunks.[chunkIndex] <- Array.zeroCreateUnchecked (Math.Min(chunkSize,array.Length-i+1))
let chunk = chunks.[chunkIndex]
// printf "allocated new chunk[%A] size %A\n" chunkIndex chunks.[chunkIndex].Length
count <- 0
while count < chunk.Length && i < array.Length do
let e = array.[i]
if f e then
chunk.[count] <- e
count <- count + 1
i <- i + 1
totalSize <- totalSize + count
chunkIndex <- chunkIndex + 1
let res : 'T[] = Array.zeroCreate totalSize
let mutable start = 0
for i = 0 to chunks.Length-1 do
if chunks.[i] <> empty then
let len = if i = chunks.Length-1 || chunks.[i+1] = empty then count else chunks.[i].Length
Array.Copy(chunks.[i],0,res,start,len)
start <- start + len
res
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment