Created
August 23, 2016 04:12
-
-
Save manofstick/0fed221b1ca4abcd65a632915d9dc48f to your computer and use it in GitHub Desktop.
Not very portable version of philter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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