Skip to content

Instantly share code, notes, and snippets.

@theburningmonk
Created June 4, 2012 16:22
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 theburningmonk/2869351 to your computer and use it in GitHub Desktop.
Save theburningmonk/2869351 to your computer and use it in GitHub Desktop.
Shadow the Seq module's iter and map functions to include type test
module Seq
// Shadowing the iter function is probably ok.
let iter f (seq : seq<'a>) =
match seq with
| :? array<'a> -> Array.iter f (seq :?> array<'a>)
| :? list<'a> -> List.iter f (seq :?> list<'a>)
| _ -> Seq.iter f seq
// Though you probably shouldn't shadow the map function!!
let map f (seq : seq<'a>) =
match seq with
| :? array<'a> -> Array.map f (seq :?> array<'a>) :> seq<'a>
| :? list<'a> -> List.map f (seq :?> list<'a>) :> seq<'a>
| _ -> Seq.map f seq
let toArray (seq : seq<'a>) =
match seq with
| :? array<'a> -> seq :?> array<'a>
| _ -> Seq.toArray seq
let toList (seq : seq<'a>) =
match seq with
| :? list<'a> -> seq :?> list<'a>
| _ -> Seq.toList seq
#load "Module1.fs"
let n = 10000000
let doNothing _ = ()
let incr x = x + 1
let arr = Array.init n (fun _ -> 0)
let rec buildList n acc i = if i = n then acc else buildList n (0 :: acc) (i + 1)
let lst = buildList n [] 0
#time
arr |> Array.iter doNothing // 14ms
arr |> Seq.iter doNothing // 17ms
arr |> Collections.Seq.iter doNothing // 56ms
lst |> List.iter doNothing // 19ms
lst |> Seq.iter doNothing // 19ms
lst |> Collections.Seq.iter doNothing // 89ms
arr |> Array.map incr // 31ms
arr |> Seq.map incr |> Seq.toArray // 21ms
arr |> Seq.map incr
|> Collections.Seq.toArray // 39ms
arr |> Collections.Seq.map incr
|> Collections.Seq.toArray // 233ms
lst |> List.map incr // 776ms
lst |> Seq.map incr |> Seq.toList // 768ms
lst |> Seq.map incr
|> Collections.Seq.toList // 853ms
lst |> Collections.Seq.map incr
|> Collections.Seq.toList // 1683ms
@mausch
Copy link

mausch commented Jun 28, 2012

Just checked and FSharp.Core 4.3.0.0 does not specialize Seq.head or Seq.map

@theburningmonk
Copy link
Author

That's a shame, but easy enough to shadow those operations anyway, think it's worth adding to fsharpx?

@mausch
Copy link

mausch commented Jul 8, 2012

I think it's definitely worth checking if these optimizations really improve the performance in most cases.And if they do, then of course they would be a great match to add to FSharpx!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment