Skip to content

Instantly share code, notes, and snippets.

@manofstick
Created August 23, 2016 04:12
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 manofstick/0fed221b1ca4abcd65a632915d9dc48f to your computer and use it in GitHub Desktop.
Save manofstick/0fed221b1ca4abcd65a632915d9dc48f to your computer and use it in GitHub Desktop.
Not very portable version of philter
module NotFastInBenchmarkDotNet
open System.Runtime.InteropServices
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// NOTE THAT THIS IS NOT PARTICULARLY PORTABLE, AS I'M RELYING ON PARTICULAR ENDIANNESS
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
[<Struct; StructLayout (LayoutKind.Explicit); NoComparison; NoEquality>]
type private BoolToUint32 =
[<FieldOffset 0>] val mutable Bool : bool
[<FieldOffset 0>] val mutable UInt32 : uint32
let philter32 f (source: 'T[]) =
let thirtytooth = source.Length/32
let filterMaskMap = Array.zeroCreate<uint32> (thirtytooth+1)
let mutable filteredCount = 0
let sourceBatchEnd = thirtytooth * 32
let mutable sourceIdx = 0
let mutable _00 = BoolToUint32 ()
let mutable _01 = BoolToUint32 ()
let mutable _02 = BoolToUint32 ()
let mutable _03 = BoolToUint32 ()
let mutable _04 = BoolToUint32 ()
let mutable _05 = BoolToUint32 ()
let mutable _06 = BoolToUint32 ()
let mutable _07 = BoolToUint32 ()
let mutable _08 = BoolToUint32 ()
let mutable _09 = BoolToUint32 ()
let mutable _0A = BoolToUint32 ()
let mutable _0B = BoolToUint32 ()
let mutable _0C = BoolToUint32 ()
let mutable _0D = BoolToUint32 ()
let mutable _0E = BoolToUint32 ()
let mutable _0F = BoolToUint32 ()
let mutable _10 = BoolToUint32 ()
let mutable _11 = BoolToUint32 ()
let mutable _12 = BoolToUint32 ()
let mutable _13 = BoolToUint32 ()
let mutable _14 = BoolToUint32 ()
let mutable _15 = BoolToUint32 ()
let mutable _16 = BoolToUint32 ()
let mutable _17 = BoolToUint32 ()
let mutable _18 = BoolToUint32 ()
let mutable _19 = BoolToUint32 ()
let mutable _1A = BoolToUint32 ()
let mutable _1B = BoolToUint32 ()
let mutable _1C = BoolToUint32 ()
let mutable _1D = BoolToUint32 ()
let mutable _1E = BoolToUint32 ()
let mutable _1F = BoolToUint32 ()
while sourceIdx < sourceBatchEnd do
_00.Bool <- f source.[sourceIdx+0x00]
_01.Bool <- f source.[sourceIdx+0x01]
_02.Bool <- f source.[sourceIdx+0x02]
_03.Bool <- f source.[sourceIdx+0x03]
_04.Bool <- f source.[sourceIdx+0x04]
_05.Bool <- f source.[sourceIdx+0x05]
_06.Bool <- f source.[sourceIdx+0x06]
_07.Bool <- f source.[sourceIdx+0x07]
_08.Bool <- f source.[sourceIdx+0x08]
_09.Bool <- f source.[sourceIdx+0x09]
_0A.Bool <- f source.[sourceIdx+0x0A]
_0B.Bool <- f source.[sourceIdx+0x0B]
_0C.Bool <- f source.[sourceIdx+0x0C]
_0D.Bool <- f source.[sourceIdx+0x0D]
_0E.Bool <- f source.[sourceIdx+0x0E]
_0F.Bool <- f source.[sourceIdx+0x0F]
_10.Bool <- f source.[sourceIdx+0x10]
_11.Bool <- f source.[sourceIdx+0x11]
_12.Bool <- f source.[sourceIdx+0x12]
_13.Bool <- f source.[sourceIdx+0x13]
_14.Bool <- f source.[sourceIdx+0x14]
_15.Bool <- f source.[sourceIdx+0x15]
_16.Bool <- f source.[sourceIdx+0x16]
_17.Bool <- f source.[sourceIdx+0x17]
_18.Bool <- f source.[sourceIdx+0x18]
_19.Bool <- f source.[sourceIdx+0x19]
_1A.Bool <- f source.[sourceIdx+0x1A]
_1B.Bool <- f source.[sourceIdx+0x1B]
_1C.Bool <- f source.[sourceIdx+0x1C]
_1D.Bool <- f source.[sourceIdx+0x1D]
_1E.Bool <- f source.[sourceIdx+0x1E]
_1F.Bool <- f source.[sourceIdx+0x1F]
let filterMask =
_00.UInt32 * 0x00000001u
||| _01.UInt32 * 0x00000002u
||| _02.UInt32 * 0x00000004u
||| _03.UInt32 * 0x00000008u
||| _04.UInt32 * 0x00000010u
||| _05.UInt32 * 0x00000020u
||| _06.UInt32 * 0x00000040u
||| _07.UInt32 * 0x00000080u
||| _08.UInt32 * 0x00000100u
||| _09.UInt32 * 0x00000200u
||| _0A.UInt32 * 0x00000400u
||| _0B.UInt32 * 0x00000800u
||| _0C.UInt32 * 0x00001000u
||| _0D.UInt32 * 0x00002000u
||| _0E.UInt32 * 0x00004000u
||| _0F.UInt32 * 0x00008000u
||| _10.UInt32 * 0x00010000u
||| _11.UInt32 * 0x00020000u
||| _12.UInt32 * 0x00040000u
||| _13.UInt32 * 0x00080000u
||| _14.UInt32 * 0x00100000u
||| _15.UInt32 * 0x00200000u
||| _16.UInt32 * 0x00400000u
||| _17.UInt32 * 0x00800000u
||| _18.UInt32 * 0x01000000u
||| _19.UInt32 * 0x02000000u
||| _1A.UInt32 * 0x04000000u
||| _1B.UInt32 * 0x08000000u
||| _1C.UInt32 * 0x10000000u
||| _1D.UInt32 * 0x20000000u
||| _1E.UInt32 * 0x40000000u
||| _1F.UInt32 * 0x80000000u
let filtered =
_00.UInt32
+ _01.UInt32
+ _02.UInt32
+ _03.UInt32
+ _04.UInt32
+ _05.UInt32
+ _06.UInt32
+ _07.UInt32
+ _08.UInt32
+ _09.UInt32
+ _0A.UInt32
+ _0B.UInt32
+ _0C.UInt32
+ _0D.UInt32
+ _0E.UInt32
+ _0F.UInt32
+ _10.UInt32
+ _11.UInt32
+ _12.UInt32
+ _13.UInt32
+ _14.UInt32
+ _15.UInt32
+ _16.UInt32
+ _17.UInt32
+ _18.UInt32
+ _19.UInt32
+ _1A.UInt32
+ _1B.UInt32
+ _1C.UInt32
+ _1D.UInt32
+ _1E.UInt32
+ _1F.UInt32
filteredCount <- filteredCount + int filtered
filterMaskMap.[sourceIdx / 32] <- filterMask
sourceIdx <- sourceIdx + 32
if sourceIdx < source.Length then
let mutable filterMask = 0u
let mutable elementMask = 1u
while sourceIdx < source.Length do
if f source.[sourceIdx] then filterMask <- filterMask ||| elementMask; filteredCount <- filteredCount + 1
elementMask <- elementMask <<< 1
sourceIdx <- sourceIdx + 1
filterMaskMap.[filterMaskMap.Length-1] <- filterMask
if filteredCount = 0 then [||]
else
let res = Array.zeroCreate filteredCount
if source.Length = res.Length
then System.Array.Copy (source, res, filteredCount)
else
let mutable resIdx = 0
sourceIdx <- 0
for filterMask in filterMaskMap do
if filterMask <> 0u then
if filterMask &&& 0x00000001u <> 0u then res.[resIdx] <- source.[sourceIdx+0x00]; resIdx <- resIdx + 1
if filterMask &&& 0x00000002u <> 0u then res.[resIdx] <- source.[sourceIdx+0x01]; resIdx <- resIdx + 1
if filterMask &&& 0x00000004u <> 0u then res.[resIdx] <- source.[sourceIdx+0x02]; resIdx <- resIdx + 1
if filterMask &&& 0x00000008u <> 0u then res.[resIdx] <- source.[sourceIdx+0x03]; resIdx <- resIdx + 1
if filterMask &&& 0x00000010u <> 0u then res.[resIdx] <- source.[sourceIdx+0x04]; resIdx <- resIdx + 1
if filterMask &&& 0x00000020u <> 0u then res.[resIdx] <- source.[sourceIdx+0x05]; resIdx <- resIdx + 1
if filterMask &&& 0x00000040u <> 0u then res.[resIdx] <- source.[sourceIdx+0x06]; resIdx <- resIdx + 1
if filterMask &&& 0x00000080u <> 0u then res.[resIdx] <- source.[sourceIdx+0x07]; resIdx <- resIdx + 1
if filterMask &&& 0x00000100u <> 0u then res.[resIdx] <- source.[sourceIdx+0x08]; resIdx <- resIdx + 1
if filterMask &&& 0x00000200u <> 0u then res.[resIdx] <- source.[sourceIdx+0x09]; resIdx <- resIdx + 1
if filterMask &&& 0x00000400u <> 0u then res.[resIdx] <- source.[sourceIdx+0x0A]; resIdx <- resIdx + 1
if filterMask &&& 0x00000800u <> 0u then res.[resIdx] <- source.[sourceIdx+0x0B]; resIdx <- resIdx + 1
if filterMask &&& 0x00001000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x0C]; resIdx <- resIdx + 1
if filterMask &&& 0x00002000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x0D]; resIdx <- resIdx + 1
if filterMask &&& 0x00004000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x0E]; resIdx <- resIdx + 1
if filterMask &&& 0x00008000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x0F]; resIdx <- resIdx + 1
if filterMask &&& 0x00010000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x10]; resIdx <- resIdx + 1
if filterMask &&& 0x00020000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x11]; resIdx <- resIdx + 1
if filterMask &&& 0x00040000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x12]; resIdx <- resIdx + 1
if filterMask &&& 0x00080000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x13]; resIdx <- resIdx + 1
if filterMask &&& 0x00100000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x14]; resIdx <- resIdx + 1
if filterMask &&& 0x00200000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x15]; resIdx <- resIdx + 1
if filterMask &&& 0x00400000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x16]; resIdx <- resIdx + 1
if filterMask &&& 0x00800000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x17]; resIdx <- resIdx + 1
if filterMask &&& 0x01000000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x18]; resIdx <- resIdx + 1
if filterMask &&& 0x02000000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x19]; resIdx <- resIdx + 1
if filterMask &&& 0x04000000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x1A]; resIdx <- resIdx + 1
if filterMask &&& 0x08000000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x1B]; resIdx <- resIdx + 1
if filterMask &&& 0x10000000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x1C]; resIdx <- resIdx + 1
if filterMask &&& 0x20000000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x1D]; resIdx <- resIdx + 1
if filterMask &&& 0x40000000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x1E]; resIdx <- resIdx + 1
if filterMask &&& 0x80000000u <> 0u then res.[resIdx] <- source.[sourceIdx+0x1F]; resIdx <- resIdx + 1
sourceIdx <- sourceIdx + 32
res
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment