From 946874fcd194f9520b35a8dc23b5a02c677f43af Mon Sep 17 00:00:00 2001 From: Hugo Musso Gualandi Date: Wed, 18 Aug 2021 00:10:15 -0300 Subject: [PATCH] Add Stream Sieve benchmark from Typed Racket Closes #427. --- benchmarks/streamSieve/lua.lua | 67 ++++++++++++++++++++++++++++++ benchmarks/streamSieve/main.lua | 11 +++++ benchmarks/streamSieve/pallene.pln | 67 ++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 benchmarks/streamSieve/lua.lua create mode 100644 benchmarks/streamSieve/main.lua create mode 100644 benchmarks/streamSieve/pallene.pln diff --git a/benchmarks/streamSieve/lua.lua b/benchmarks/streamSieve/lua.lua new file mode 100644 index 00000000..0fdb594e --- /dev/null +++ b/benchmarks/streamSieve/lua.lua @@ -0,0 +1,67 @@ +-- Naive stream-based prime sieve benchmark. (Based on a typed-racket benchmark) +-- Based on https://github.com/bennn/gtp-benchmarks/tree/master/benchmarks/sieve + +local m = {} + +---------------------------------------------- + +-- Simple streams library for building infinite lists. +-- A stream is a cons of a value and a thunk that computes the next value. + + + +-- TODO: with recursive types, this could be (any -> Stream) + + +local function make_stream(first, rest) + return {first=first, rest=rest} +end + +local function stream_head(st) + return st.first +end + +local function stream_tail(st) + return st.rest() +end + +local function stream_get(st, n) + for _ = 1, n-1 do + st = stream_tail(st) + end + return stream_head(st) +end + +---------------------------------------------- + +-- Build a stream of integers starting from 1 +local function count_from(n) + return make_stream(n, function() return count_from(n+1) end) +end + +-- Filter all multiples of n +local function sift(n, st) + local hd = stream_head(st) + local tl = stream_tail(st) + if hd % n == 0 then + return sift(n, tl) + else + return make_stream(hd, function() return sift(n, tl) end) + end +end + +-- Naive sieve of Erasthostenes +local function sieve(st) + local hd = stream_head(st) + local tl = stream_tail(st) + return make_stream(hd, function() return sieve(sift(hd, tl)) end) +end + +---- + +function m.get_prime(n) + local primes = sieve(count_from(2)) + return stream_get(primes, n) +end + +return m diff --git a/benchmarks/streamSieve/main.lua b/benchmarks/streamSieve/main.lua new file mode 100644 index 00000000..03635438 --- /dev/null +++ b/benchmarks/streamSieve/main.lua @@ -0,0 +1,11 @@ +-- +-- This benchmark runs a naive prime sieve using lazy streams. Taken from the +-- Typed Racket benchmarks: +-- * https://github.com/nuprl/gradual-typing-performance/tree/master/benchmarks/sieve +-- * https://github.com/bennn/gtp-benchmarks/tree/master/benchmarks/sieve +-- + +local sieve = require(arg[1]) +local N = tonumber(arg[2]) or 2000 -- or 5500 + +print(string.format("primes(%d) = %d", N, sieve.get_prime(N))) diff --git a/benchmarks/streamSieve/pallene.pln b/benchmarks/streamSieve/pallene.pln new file mode 100644 index 00000000..3a4e4c2b --- /dev/null +++ b/benchmarks/streamSieve/pallene.pln @@ -0,0 +1,67 @@ +-- Naive stream-based prime sieve benchmark. (Based on a typed-racket benchmark) +-- Based on https://github.com/bennn/gtp-benchmarks/tree/master/benchmarks/sieve + +local m = {} + +---------------------------------------------- + +-- Simple streams library for building infinite lists. +-- A stream is a cons of a value and a thunk that computes the next value. + +record Stream + first: any + rest: () -> any -- TODO: with recursive types, this could be (any -> Stream) +end + +local function make_stream(first: any, rest: ()->any): Stream + return {first=first, rest=rest} +end + +local function stream_head(st: Stream): any + return st.first +end + +local function stream_tail(st: Stream): Stream + return st.rest() as Stream +end + +local function stream_get(st: Stream, n: integer): any + for _ = 1, n-1 do + st = stream_tail(st) + end + return stream_head(st) +end + +---------------------------------------------- + +-- Build a stream of integers starting from 1 +local function count_from(n: integer): Stream + return make_stream(n, function() return count_from(n+1) end) +end + +-- Filter all multiples of n +local function sift(n: integer, st: Stream): Stream + local hd = stream_head(st) as integer + local tl = stream_tail(st) as Stream + if hd % n == 0 then + return sift(n, tl) + else + return make_stream(hd, function() return sift(n, tl) end) + end +end + +-- Naive sieve of Erasthostenes +local function sieve(st: Stream): Stream + local hd = stream_head(st) as integer + local tl = stream_tail(st) as Stream + return make_stream(hd, function() return sieve(sift(hd, tl)) end) +end + +---- + +function m.get_prime(n: integer): integer + local primes = sieve(count_from(2)) + return stream_get(primes, n) +end + +return m