Created
January 21, 2016 14:41
-
-
Save m4ktub/1818fb6c8b509a260777 to your computer and use it in GitHub Desktop.
Pi Gregory Series in Pony (based on Akka tutorial)
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
| 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