Skip to content

Instantly share code, notes, and snippets.

@m4ktub
Created January 21, 2016 14:41
Show Gist options
  • Select an option

  • Save m4ktub/1818fb6c8b509a260777 to your computer and use it in GitHub Desktop.

Select an option

Save m4ktub/1818fb6c8b509a260777 to your computer and use it in GitHub Desktop.
Pi Gregory Series in Pony (based on Akka tutorial)
use "time"
use "collections"
interface Receiver
"""
The receiver interface is used allow the sender receive the result
value. This could be used to send the result to another actor.
"""
be result(value: F64)
actor Worker
fun calculate_pi_for(start: U64, elements: U64): F64 =>
var acc: F64 = 0.0
for i in Range(start, start + elements) do
let a = (1 - ((i.i64() % 2) * 2))
let b = ((2 * i) + 1)
acc = acc + (4.0 * (a.f64() / b.f64()))
end
acc
be work(receiver: Receiver tag, start: U64, elements: U64) =>
receiver.result(calculate_pi_for(start, elements))
actor RoundRobinWorker
"""
This is a concrete implementation of a behavior router. The generalization
of the router would imply the generalization of argument passing.
"""
let _workers: List[Worker] = List[Worker]
var _pos: U64 = 0
new create(workers: U64) =>
for i in Range(0, workers) do
_workers.push(Worker)
end
be work(receiver: Receiver tag, start: U64, elements: U64) =>
match try _workers(_pos) else None end
| let w: Worker => w.work(receiver, start, elements)
end
_pos = (_pos + 1) % _workers.size()
actor Master is Receiver
let _num_elements: U64
let _num_messages: U64
let _listener: Listener
let _router: RoundRobinWorker
let _start: U64
var _pi: F64 = 0.0
var _num_results: U64 = 0
new create(workers: U64, elements: U64, messages: U64, listener: Listener) =>
_router = RoundRobinWorker(workers)
_listener = listener
_num_elements = elements
_num_messages = messages
_start = Time.millis()
be calculate() =>
for i in Range(0, _num_messages) do
_router.work(this, i * _num_elements, _num_elements)
end
be result(value: F64) =>
_pi = _pi + value
_num_results = _num_results + 1
if _num_results == _num_messages then
_listener.pi_approximation(_pi, Time.millis() - _start)
end
actor Listener
let _out: StdStream
new create(out: StdStream) =>
_out = out
be pi_approximation(pi: F64, duration: U64) =>
_out.print("Pi approximation: " + pi.string(FloatFix where prec = 16))
_out.print("Calculation time: " + duration.string() + " ms")
actor Main
new create(env: Env) =>
calculate(env where
workers = 4,
elements = 10000,
messages = 10000)
fun calculate(env: Env, workers: U64, elements: U64, messages: U64) =>
let listener = Listener(env.out)
let master = Master(workers, elements, messages, listener)
master.calculate()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment