Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Benchmark lazy infinite sieve of Eratosthenes #11351

Merged
merged 5 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion project/GraalVM.scala
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ object GraalVM {
)

val insightPkgs = Seq(
"org.graalvm.tools" % "insight-tool" % version
"org.graalvm.tools" % "insight-tool" % version,
"org.graalvm.tools" % "insight-heap-tool" % version
)

private val espressoPkgs =
Expand Down
44 changes: 44 additions & 0 deletions test/Benchmarks/src/Sieve/Lazy_Sieve.enso
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from Standard.Base import all

type Stream
private Item head:Integer ~tail:Stream

primes -> Stream =
is_prime s:Stream n:Integer =
if n%s.head == 0 then False else
if s.head*s.head > n then True else
@Tail_Call is_prime s.tail n

find_next primes:Stream n:Integer =
n_is_prime = is_prime primes n

if n_is_prime then Stream.Item n (find_next primes n+1) else
@Tail_Call find_next primes n+1


p = Stream.Item 2 (find_next p 3)
p


compute_nth_prime n -> Integer =
take_nth s:Stream n:Integer -> Integer =
if n <= 1 then s.head else
@Tail_Call take_nth s.tail n-1

take_nth primes n



main n=Nothing =
print_nth s:Stream n:Integer|Nothing -> Nothing =
if n.is_nothing.not && n <= 0 then IO.println "" else
IO.print s.head
IO.print " "
@Tail_Call print_nth s.tail (n.if_not_nothing n-1)

compute_and_print_nth nth:Integer|Nothing =
p = primes
print_nth p nth

compute_and_print_nth n

6 changes: 6 additions & 0 deletions test/Benchmarks/src/Sieve/Main.enso
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ from Standard.Base import all

from Standard.Test import Bench

import project.Sieve.Lazy_Sieve

import project.Sieve.Sieve_Original
import project.Sieve.Sieve_Ascribed
import project.Sieve.Sieve_Ascribed_With_Return_Checks
Expand Down Expand Up @@ -36,3 +38,7 @@ collect_benches = Bench.build builder->
assert_prime <| Sieve_Java_Script.compute_nth_prime_natural_in_js 100000
group_builder.specify "Java_Script_Filter" <|
assert_prime <| Sieve_Java_Script.compute_nth_prime_filter_in_js 100000

builder.group "Sieve_Lazy" options group_builder->
group_builder.specify "Original" <|
assert_prime <| Lazy_Sieve.compute_nth_prime 100000
50 changes: 50 additions & 0 deletions test/Benchmarks/src/Sieve/heap_dump_lazy_sieve.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// Demo script showing a "serialization" of an Enso atom structure
// to a `.hprof` file which can be opened and analyzed in VisualVM
//
// Based on following tutorial:
// https://www.graalvm.org/jdk21/tools/graalvm-insight/manual/#heap-dumping
//
// Execute from `sbt` as:
// ```
// sbt:enso> runEngineDistribution \
// --vm.D=polyglot.heap.dump=/tmp/sieve.hprof \
// --vm.D=polyglot.insight=Benchmarks/src/Sieve/heap_dump_lazy_sieve.js \
// --run test/Benchmarks/src/Sieve/Lazy_Sieve.enso
// 10000
// ```
//
// This GraalVM script waits for the end execution of `compute_and_print_nth` function
// to store value of its `p` local variable (containing linked list of prime numbers)
// into `/tmp/sieve.hprof` - a GraalVM serialization for Truffle languages!
Copy link
Member Author

@JaroslavTulach JaroslavTulach Oct 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To generate this heap dump execute:

sbt:enso> runEngineDistribution --vm.D=polyglot.heap.dump=/tmp/sieve.hprof --vm.D=polyglot.insight=Benchmarks/src/Sieve/heap_dump_lazy_sieve.js --run test/Benchmarks/src/Sieve/Lazy_Sieve.enso 10000

This is how the heap dump looks like in VisualVM:

Enso heap in VisualVM


insight.on(
'return',
(ctx, frame) => {
for (let p in frame) {
print(`found ${p} with ${frame[p]} value`)
}
let value = frame.p
heap.dump({
format: '1.0',
depth: 5000,
events: [
{
stack: [
{
at: ctx,
frame: {
primes: value,
},
},
],
},
],
})
print('Heap dump generated!')
},
{
roots: true,
rootNameFilter: '.*compute_and_print_nth',
},
)
Loading