Skip to content

Instantly share code, notes, and snippets.

@altbodhi
Created November 21, 2023 03:12
Show Gist options
  • Save altbodhi/eefdd918ce67a5fc379117806043f891 to your computer and use it in GitHub Desktop.
Save altbodhi/eefdd918ce67a5fc379117806043f891 to your computer and use it in GitHub Desktop.
Atom in F#
open System
type Message<'a> =
| Get of AsyncReplyChannel<'a>
| Update of AsyncReplyChannel<'a> * ('a -> 'a)
type Atom<'a>(o: 'a) =
let agent =
MailboxProcessor.Start(fun b ->
let rec loop (acc) =
async {
let! m = b.Receive()
match m with
| Update(repl, fn) ->
let nw = fn acc
repl.Reply nw
return! loop nw
| Get repl ->
repl.Reply acc
return! loop acc
}
loop o)
member it.Get() =
agent.PostAndReply(fun (rc: AsyncReplyChannel<'a>) -> Get rc)
member it.Update(fn: 'a -> 'a) =
agent.PostAndReply(fun rc -> Update(rc, fn))
let atom = Atom(0)
let pritnln (line: string) = Console.WriteLine line
let max = 1_000_000
let proc xs =
xs
|> Array.iter (fun i ->
let v =
if i % 2 = 0 then
atom.Update(fun x -> x + i)
else
atom.Get()
let tid = System.Threading.Thread.CurrentThread.ManagedThreadId
pritnln (v |> sprintf "i = %d, tid = %d, v = %A;" i tid))
let sequ xs =
let count = xs |> Array.length
xs
|> Array.chunkBySize (count / Environment.ProcessorCount)
|> Array.Parallel.iter proc
let xs = [| 1..max |]
atom.Update(fun _ -> 0) |> ignore
#time
sequ xs
proc xs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment