-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Stream Sieve benchmark from Typed Racket
Closes #427.
- Loading branch information
Showing
3 changed files
with
145 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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))) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |