├── go ├── go.mod └── sieve.go ├── c ├── nbproject │ ├── project.properties │ ├── project.xml │ ├── Makefile-variables.mk │ ├── Package-Debug.bash │ ├── Package-Release.bash │ ├── Makefile-Debug.mk │ ├── Makefile-Release.mk │ ├── configurations.xml │ └── Makefile-impl.mk ├── .dep.inc ├── natural.c ├── natural.h ├── filter.h ├── primes.h ├── primes.c ├── filter.c ├── main.c └── Makefile ├── R+js ├── sieve.R ├── fromjava │ ├── nbactions.xml │ ├── nb-configuration.xml │ ├── src │ │ └── main │ │ │ └── java │ │ │ └── org │ │ │ └── apidesign │ │ │ └── demo │ │ │ └── rjs │ │ │ └── fromjava │ │ │ └── Main.java │ └── pom.xml └── sieve.js ├── java ├── algorithm │ ├── Dockerfile │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── apidesign │ │ │ │ └── demo │ │ │ │ └── sieve │ │ │ │ └── eratosthenes │ │ │ │ ├── Natural.java │ │ │ │ ├── Filter.java │ │ │ │ └── Primes.java │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── apidesign │ │ │ └── demo │ │ │ └── sieve │ │ │ └── eratosthenes │ │ │ └── PrimesTest.java │ ├── nbactions.xml │ └── pom.xml ├── client-web │ ├── src │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ ├── teavm │ │ │ │ └── classlib │ │ │ │ │ └── java │ │ │ │ │ └── util │ │ │ │ │ ├── TEventListener.java │ │ │ │ │ └── TEventObject.java │ │ │ │ └── apidesign │ │ │ │ └── demo │ │ │ │ └── sieve │ │ │ │ └── BrowserMain.java │ │ │ └── assembly │ │ │ ├── teavm.xml │ │ │ └── bck2brwsr.xml │ ├── nbactions.xml │ └── pom.xml ├── client │ ├── src │ │ ├── test │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── apidesign │ │ │ │ └── demo │ │ │ │ └── sieve │ │ │ │ └── DataModelTest.java │ │ └── main │ │ │ ├── webapp │ │ │ └── pages │ │ │ │ └── index.html │ │ │ ├── java │ │ │ └── org │ │ │ │ └── apidesign │ │ │ │ └── demo │ │ │ │ └── sieve │ │ │ │ ├── Main.java │ │ │ │ └── DataModel.java │ │ │ └── assembly │ │ │ ├── javafx.xml │ │ │ └── webpages.xml │ ├── nbactions.xml │ └── pom.xml └── pom.xml ├── ruby+js ├── sieve.rb ├── fromjava │ ├── nbactions.xml │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── apidesign │ │ └── demo │ │ └── rubyjs │ │ └── fromjava │ │ └── Main.java └── sieve.js ├── haskell └── sieve.hs ├── python+ruby+js ├── sieve.py ├── sieve.rb ├── fromjava │ ├── nbactions.xml │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── apidesign │ │ └── demo │ │ └── pythonrubyjs │ │ └── fromjava │ │ └── Main.java └── sieve.js ├── .gitignore ├── R ├── sieve.R ├── nbactions.xml ├── nb-configuration.xml ├── src │ └── main │ │ └── java │ │ └── org │ │ └── apidesign │ │ └── demo │ │ └── sieve │ │ └── r │ │ └── Main.java └── pom.xml ├── js ├── index.html ├── fromjava │ ├── nbactions.xml │ ├── src │ │ └── main │ │ │ └── java │ │ │ └── org │ │ │ └── apidesign │ │ │ └── demo │ │ │ └── trufflejs │ │ │ └── Main.java │ └── pom.xml └── sieve.js ├── .travis.yml ├── LICENSE ├── crystal └── sieve.cr ├── ruby └── sieve.rb ├── erlang └── sieve.erl ├── python └── sieve.py ├── .test.sh ├── lua └── sieve.lua └── README.md /go/go.mod: -------------------------------------------------------------------------------- 1 | module apidesign.org/sieve 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /c/nbproject/project.properties: -------------------------------------------------------------------------------- 1 | #Thu Jun 23 09:40:26 CEST 2016 2 | -------------------------------------------------------------------------------- /R+js/sieve.R: -------------------------------------------------------------------------------- 1 | natural <- function() { 2 | 2:99999999 3 | } 4 | export('Natural', natural) 5 | -------------------------------------------------------------------------------- /java/algorithm/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.6 2 | COPY ./target/sieve /bin/sieve 3 | CMD /bin/sieve 4 | 5 | -------------------------------------------------------------------------------- /java/client-web/src/main/java/org/teavm/classlib/java/util/TEventListener.java: -------------------------------------------------------------------------------- 1 | package org.teavm.classlib.java.util; 2 | 3 | public interface TEventListener { 4 | } 5 | -------------------------------------------------------------------------------- /c/.dep.inc: -------------------------------------------------------------------------------- 1 | # This code depends on make tool being used 2 | DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES} ${TESTOBJECTFILES})) 3 | ifneq (${DEPFILES},) 4 | include ${DEPFILES} 5 | endif 6 | -------------------------------------------------------------------------------- /c/natural.c: -------------------------------------------------------------------------------- 1 | #include "natural.h" 2 | 3 | void initNatural(NaturalType* self) { 4 | self->x = 2; 5 | } 6 | 7 | int nextNatural(NaturalType* self) { 8 | return self->x++; 9 | } 10 | -------------------------------------------------------------------------------- /ruby+js/sieve.rb: -------------------------------------------------------------------------------- 1 | class Natural 2 | def initialize 3 | @x = 1 4 | end 5 | 6 | def next 7 | @x += 1 8 | end 9 | end 10 | 11 | def create 12 | Natural.new 13 | end 14 | 15 | Polyglot.export("Natural", method(:create)); 16 | -------------------------------------------------------------------------------- /c/natural.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | typedef struct Natural { 7 | int x; 8 | } NaturalType; 9 | 10 | void initNatural(NaturalType* self); 11 | int nextNatural(NaturalType* self); 12 | -------------------------------------------------------------------------------- /haskell/sieve.hs: -------------------------------------------------------------------------------- 1 | primes :: [Int] 2 | primes = 2 : filter (prime primes) [3,5..] where 3 | prime (p:ps) n = p*p > n || rem n p /= 0 && prime ps n 4 | 5 | main = do 6 | print "One hundred thousand prime number is" 7 | print $ last $ take 100000 primes 8 | -------------------------------------------------------------------------------- /java/algorithm/src/main/java/org/apidesign/demo/sieve/eratosthenes/Natural.java: -------------------------------------------------------------------------------- 1 | package org.apidesign.demo.sieve.eratosthenes; 2 | 3 | final class Natural { 4 | private int cnt = 2; 5 | 6 | int next() { 7 | return cnt++; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /c/filter.h: -------------------------------------------------------------------------------- 1 | 2 | typedef struct Filter { 3 | int number; 4 | struct Filter *next; 5 | struct Filter *last; 6 | } FilterType; 7 | 8 | FilterType* newFilter(int n); 9 | void releaseFilter(FilterType* filter); 10 | int acceptAndAdd(FilterType* filter, int n); 11 | -------------------------------------------------------------------------------- /python+ruby+js/sieve.py: -------------------------------------------------------------------------------- 1 | import polyglot 2 | 3 | class Natural: 4 | n = 2 5 | 6 | def next(self): 7 | r = self.n 8 | self.n = self.n + 1 9 | return r 10 | 11 | def create(): 12 | return Natural() 13 | 14 | polyglot.export_value("Natural", create); 15 | -------------------------------------------------------------------------------- /java/client-web/src/main/java/org/apidesign/demo/sieve/BrowserMain.java: -------------------------------------------------------------------------------- 1 | package org.apidesign.demo.sieve; 2 | 3 | public class BrowserMain { 4 | private BrowserMain() { 5 | } 6 | 7 | public static void main(String... args) throws Exception { 8 | Main.onPageLoad(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /c/primes.h: -------------------------------------------------------------------------------- 1 | #include "natural.h" 2 | #include "filter.h" 3 | 4 | typedef struct Primes { 5 | NaturalType* natural; 6 | FilterType* filter; 7 | } PrimesType; 8 | 9 | void initPrimes(PrimesType* self, NaturalType* natural); 10 | void releasePrimes(PrimesType* self); 11 | int nextPrime(PrimesType* self); 12 | -------------------------------------------------------------------------------- /java/client/src/test/java/org/apidesign/demo/sieve/DataModelTest.java: -------------------------------------------------------------------------------- 1 | package org.apidesign.demo.sieve; 2 | 3 | import static org.testng.Assert.*; 4 | import org.testng.annotations.Test; 5 | 6 | public class DataModelTest { 7 | @Test public void testUIModelWithoutUI() { 8 | Data model = new Data(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /java/client-web/src/main/java/org/teavm/classlib/java/util/TEventObject.java: -------------------------------------------------------------------------------- 1 | package org.teavm.classlib.java.util; 2 | 3 | public class TEventObject { 4 | private final Object src; 5 | 6 | public TEventObject(Object source) { 7 | this.src = source; 8 | } 9 | 10 | public Object getSource() { 11 | return src; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | pom.xml.tag 3 | pom.xml.releaseBackup 4 | pom.xml.versionsBackup 5 | pom.xml.next 6 | release.properties 7 | dependency-reduced-pom.xml 8 | buildNumber.properties 9 | .mvn/timing.properties 10 | /c/build/ 11 | /c/dist/ 12 | /c/sieve* 13 | /c/*.bc 14 | /c/nbproject/private 15 | /go/sieve 16 | /js/fromjava/nbproject/private/ 17 | /js/fromjava/dist/ 18 | /js/fromjava/build/ 19 | go/go 20 | nb-configuration.xml 21 | 22 | -------------------------------------------------------------------------------- /java/client/src/main/webapp/pages/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

Sieve of Eratosthenes

9 | 10 |
11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /java/algorithm/src/test/java/org/apidesign/demo/sieve/eratosthenes/PrimesTest.java: -------------------------------------------------------------------------------- 1 | package org.apidesign.demo.sieve.eratosthenes; 2 | 3 | import static org.testng.AssertJUnit.assertEquals; 4 | import org.testng.annotations.Test; 5 | 6 | public class PrimesTest { 7 | @Test 8 | public void fifthThousandThPrime() { 9 | Primes p = new Primes() { 10 | @Override 11 | protected void log(String msg) { 12 | } 13 | }; 14 | int last = p.compute(); 15 | assertEquals("100000th prime is", 1_299_709, last); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /c/primes.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "primes.h" 3 | 4 | void initPrimes(PrimesType* self, NaturalType* natural) { 5 | self->natural = natural; 6 | self->filter = NULL; 7 | } 8 | 9 | void releasePrimes(PrimesType* self) { 10 | releaseFilter(self->filter); 11 | } 12 | 13 | int nextPrime(PrimesType* self) { 14 | for (;;) { 15 | int n = nextNatural(self->natural); 16 | if (self->filter == NULL) { 17 | self->filter = newFilter(n); 18 | return n; 19 | } 20 | if (acceptAndAdd(self->filter, n)) { 21 | return n; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /python+ruby+js/sieve.rb: -------------------------------------------------------------------------------- 1 | class Filter 2 | attr_reader :number 3 | attr_accessor :next 4 | 5 | def initialize(number) 6 | @number = number 7 | @next = nil 8 | @last = self 9 | end 10 | 11 | def acceptAndAdd(n) 12 | filter = self 13 | upto = Math.sqrt(n) 14 | while filter 15 | if n % filter.number == 0 16 | return false 17 | end 18 | if filter.number > upto 19 | break 20 | end 21 | filter = filter.next 22 | end 23 | filter = Filter.new(n) 24 | @last.next = filter 25 | @last = filter 26 | true 27 | end 28 | end 29 | 30 | def create(n) 31 | return Filter.new(n) 32 | end 33 | 34 | Polyglot.export("Filter", method(:create)); 35 | -------------------------------------------------------------------------------- /R/sieve.R: -------------------------------------------------------------------------------- 1 | isprime <- function(num, primes, primes.length) { 2 | for (i in 1:primes.length) { 3 | if (num %% primes[i] == 0) return(FALSE); 4 | } 5 | TRUE 6 | }; 7 | 8 | findfirst <- function(fun, start) { 9 | i <- start 10 | while (TRUE) { 11 | if (fun(i)) return(i) 12 | i <- i + 1 13 | } 14 | }; 15 | 16 | sieve <- function(primeAt) { 17 | primes <- rep(2L, primeAt) 18 | for (at in 2:primeAt) { 19 | num <- primes[[at-1]]+1 20 | primes[[at]] <- findfirst(function(x) isprime(x, primes, at-1L), num+1L); 21 | } 22 | cat("Result", primes[[primeAt]], "\n"); 23 | primes[[primeAt]] 24 | }; 25 | 26 | s <- function(x) system.time(x) 27 | for (i in 1:1000) { 28 | t <- s(sieve(5000L)); 29 | cat("Took", round(t[1] * 1000), "ms\n"); 30 | } 31 | -------------------------------------------------------------------------------- /java/client/src/main/java/org/apidesign/demo/sieve/Main.java: -------------------------------------------------------------------------------- 1 | package org.apidesign.demo.sieve; 2 | 3 | import net.java.html.boot.BrowserBuilder; 4 | 5 | public final class Main { 6 | private Main() { 7 | } 8 | 9 | public static void main(String... args) throws Exception { 10 | BrowserBuilder.newBrowser(). 11 | loadPage("pages/index.html"). 12 | loadClass(Main.class). 13 | invoke("onPageLoad", args). 14 | showAndWait(); 15 | System.exit(0); 16 | } 17 | 18 | public static void onPageLoad(String... args) throws Exception { 19 | Integer repeat = null; 20 | if (args.length == 1) { 21 | repeat = Integer.parseInt(args[0]); 22 | if (repeat == 0) { 23 | repeat = null; 24 | } 25 | } 26 | DataModel.onPageLoad(repeat); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /js/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Sieve of Eratosthenes in JavaScript 4 | 5 | 6 |

Sieve of Eratosthenes in JavaScript

7 | 8 | 9 |

10 | 11 |

12 | 13 | 27 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /java/algorithm/src/main/java/org/apidesign/demo/sieve/eratosthenes/Filter.java: -------------------------------------------------------------------------------- 1 | package org.apidesign.demo.sieve.eratosthenes; 2 | 3 | final class Filter { 4 | private final int number; 5 | private Filter next; 6 | private Filter last; 7 | 8 | public Filter(int number) { 9 | this.number = number; 10 | this.last = this; 11 | } 12 | 13 | public boolean acceptAndAdd(int n) { 14 | Filter filter = this; 15 | double upto = Math.sqrt(n); 16 | for (;;) { 17 | if (n % filter.number == 0) { 18 | return false; 19 | } 20 | if (filter.number > upto) { 21 | final Filter newFilter = new Filter(n); 22 | last.next = newFilter; 23 | last = newFilter; 24 | return true; 25 | } 26 | filter = filter.next; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /c/filter.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "filter.h" 4 | 5 | FilterType* newFilter(int n) { 6 | FilterType* f = malloc(sizeof(FilterType)); 7 | f->number = n; 8 | f->next = NULL; 9 | f->last = f; 10 | return f; 11 | } 12 | 13 | void releaseFilter(FilterType* filter) { 14 | while (filter != NULL) { 15 | FilterType* next = filter->next; 16 | free(filter); 17 | filter = next; 18 | } 19 | } 20 | 21 | int acceptAndAdd(FilterType* filter, int n) { 22 | FilterType* first = filter; 23 | int upto = (int)sqrt(n); 24 | for (;;) { 25 | if (n % filter->number == 0) { 26 | return 0; 27 | } 28 | if (filter->number > upto) { 29 | break; 30 | } 31 | filter = filter->next; 32 | } 33 | FilterType* f = newFilter(n); 34 | first->last->next = f; 35 | first->last = f; 36 | return 1; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /R/nbactions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | debug 5 | 6 | jar 7 | 8 | 9 | process-classes 10 | exec:exec 11 | 12 | 13 | -J:-Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} 14 | true 15 | 16 | 17 | 18 | run 19 | 20 | jar 21 | 22 | 23 | process-classes 24 | exec:exec 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /js/fromjava/nbactions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | debug 5 | 6 | jar 7 | 8 | 9 | process-classes 10 | exec:exec 11 | 12 | 13 | -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} 14 | true 15 | 16 | 17 | 18 | run 19 | 20 | jar 21 | 22 | 23 | process-classes 24 | exec:exec 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /R+js/fromjava/nbactions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | debug 5 | 6 | jar 7 | 8 | 9 | process-classes 10 | exec:exec 11 | 12 | 13 | -J:-Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} 14 | true 15 | 16 | 17 | 18 | run 19 | 20 | jar 21 | 22 | 23 | process-classes 24 | exec:exec 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ruby+js/fromjava/nbactions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | debug 5 | 6 | jar 7 | 8 | 9 | process-classes 10 | exec:exec 11 | 12 | 13 | -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} 14 | true 15 | 16 | 17 | 18 | run 19 | 20 | jar 21 | 22 | 23 | process-classes 24 | exec:exec 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /python+ruby+js/fromjava/nbactions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | debug 5 | 6 | jar 7 | 8 | 9 | process-classes 10 | exec:exec 11 | 12 | 13 | -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} 14 | true 15 | 16 | 17 | 18 | run 19 | 20 | jar 21 | 22 | 23 | process-classes 24 | exec:exec 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | sudo: false 3 | services: 4 | - xvfb 5 | before_script: 6 | - sudo apt-get -y install $LIBS 7 | - export DISPLAY=:99.0 8 | - mkdir -p download 9 | - cd download 10 | - wget $URL 11 | - cd .. 12 | - tar fxvz download/graalvm-ce-*.tar.gz 13 | - ./graalvm-ce-*/bin/gu install -c org.graalvm.ruby 14 | - ./graalvm-ce-*/bin/gu install -c org.graalvm.R 15 | - ./graalvm-ce-*/bin/gu install -c org.graalvm.python 16 | script: 17 | - set -eo pipefail 18 | - ./.test.sh ./graalvm-ce-*/ 2>&1 | grep -v ^Computed.*Last.*one 19 | os: 20 | - linux 21 | matrix: 22 | include: 23 | - name: GraalVM 19.3.1 24 | dist: xenial 25 | env: 26 | - URL=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-19.3.1/graalvm-ce-java8-linux-amd64-19.3.1.tar.gz 27 | - LIBS=libgfortran3 28 | - name: GraalVM 20.0.0 29 | dist: bionic 30 | env: 31 | - URL=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.0.0/graalvm-ce-java8-linux-amd64-20.0.0.tar.gz 32 | - LIBS=libgfortran5 33 | -------------------------------------------------------------------------------- /R/nb-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 16 | GraalVM 17 | 18 | 19 | -------------------------------------------------------------------------------- /R+js/fromjava/nb-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 16 | GraalVM 17 | 18 | 19 | -------------------------------------------------------------------------------- /c/nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.netbeans.modules.cnd.makeproject 4 | 5 | 6 | csieve 7 | c 8 | 9 | h 10 | UTF-8 11 | 12 | 13 | 14 | 15 | Debug 16 | 1 17 | 18 | 19 | Release 20 | 1 21 | 22 | 23 | 24 | false 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /java/client/nbactions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | run 5 | 6 | process-classes 7 | exec:exec 8 | 9 | 10 | 11 | debug 12 | 13 | process-classes 14 | exec:exec 15 | 16 | 17 | true 18 | -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} 19 | 20 | 21 | 22 | CUSTOM-Build Desktop App 23 | Build Desktop App 24 | 25 | clean 26 | package 27 | 28 | 29 | desktop 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Jaroslav Tulach 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /R/src/main/java/org/apidesign/demo/sieve/r/Main.java: -------------------------------------------------------------------------------- 1 | package org.apidesign.demo.sieve.r; 2 | 3 | import com.oracle.truffle.api.source.Source; 4 | import com.oracle.truffle.api.vm.PolyglotEngine; 5 | import java.io.File; 6 | import java.net.URL; 7 | 8 | public final class Main { 9 | private Main() { 10 | } 11 | 12 | public static void main(String[] args) throws Exception { 13 | System.err.println("Setting up PolyglotEngine"); 14 | PolyglotEngine vm = PolyglotEngine.newBuilder(). 15 | build(); 16 | 17 | vm.eval(Source.fromText("", "warmup.R").withMimeType("text/x-r")); 18 | 19 | URL url = Main.class.getProtectionDomain().getCodeSource().getLocation(); 20 | File local = new File(url.toURI()); 21 | for (;;) { 22 | File sieveInR = new File(local, "sieve.R"); 23 | if (sieveInR.exists()) { 24 | break; 25 | } 26 | local = local.getParentFile(); 27 | } 28 | System.err.println("engine is ready"); 29 | 30 | Source r = Source.fromFileName(new File(local, "sieve.R").getPath()); 31 | 32 | vm.eval(r); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /R+js/fromjava/src/main/java/org/apidesign/demo/rjs/fromjava/Main.java: -------------------------------------------------------------------------------- 1 | package org.apidesign.demo.rjs.fromjava; 2 | 3 | import com.oracle.truffle.api.source.Source; 4 | import com.oracle.truffle.api.vm.PolyglotEngine; 5 | import java.io.File; 6 | import java.net.URL; 7 | 8 | public final class Main { 9 | private Main() { 10 | } 11 | 12 | public static void main(String[] args) throws Exception { 13 | System.err.println("Setting up PolyglotEngine"); 14 | PolyglotEngine vm = PolyglotEngine.newBuilder(). 15 | build(); 16 | 17 | URL url = Main.class.getProtectionDomain().getCodeSource().getLocation(); 18 | File local = new File(url.toURI()); 19 | for (;;) { 20 | File sieveInRuby = new File(local, "sieve.R"); 21 | if (sieveInRuby.exists()) { 22 | break; 23 | } 24 | local = local.getParentFile(); 25 | } 26 | 27 | Source r = Source.fromFileName(new File(local, "sieve.R").getPath()); 28 | Source js = Source.fromFileName(new File(local, "sieve.js").getPath()); 29 | 30 | vm.eval(r); 31 | vm.eval(js); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /java/client/src/main/assembly/javafx.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | javafx 6 | 7 | zip 8 | 9 | ${project.build.finalName}-app 10 | 11 | 12 | false 13 | runtime 14 | lib 15 | 16 | 17 | 18 | 19 | ${project.build.directory}/${project.build.finalName}.jar 20 | / 21 | 22 | 23 | 24 | 25 | src/main/webapp/ 26 | / 27 | 28 | pages/** 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /c/nbproject/Makefile-variables.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Generated - do not edit! 3 | # 4 | # NOCDDL 5 | # 6 | CND_BASEDIR=`pwd` 7 | CND_BUILDDIR=build 8 | CND_DISTDIR=dist 9 | # Debug configuration 10 | CND_PLATFORM_Debug=GNU-Linux 11 | CND_ARTIFACT_DIR_Debug= 12 | CND_ARTIFACT_NAME_Debug=sieve 13 | CND_ARTIFACT_PATH_Debug=sieve 14 | CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux/package 15 | CND_PACKAGE_NAME_Debug=c.tar 16 | CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux/package/c.tar 17 | # Release configuration 18 | CND_PLATFORM_Release=GNU-Linux 19 | CND_ARTIFACT_DIR_Release= 20 | CND_ARTIFACT_NAME_Release=sieve 21 | CND_ARTIFACT_PATH_Release=sieve 22 | CND_PACKAGE_DIR_Release=dist/Release/GNU-Linux/package 23 | CND_PACKAGE_NAME_Release=c.tar 24 | CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux/package/c.tar 25 | # 26 | # include compiler specific variables 27 | # 28 | # dmake command 29 | ROOT:sh = test -f nbproject/private/Makefile-variables.mk || \ 30 | (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk) 31 | # 32 | # gmake command 33 | .PHONY: $(shell test -f nbproject/private/Makefile-variables.mk || (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk)) 34 | # 35 | include nbproject/private/Makefile-variables.mk 36 | -------------------------------------------------------------------------------- /c/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "primes.h" 6 | 7 | long currentTimeMillis() { 8 | clock_t t1; 9 | 10 | t1 = clock(); 11 | return t1 / 1000; 12 | } 13 | 14 | long measure(int prntCnt, int upto) { 15 | NaturalType n; 16 | initNatural(&n); 17 | 18 | PrimesType primes; 19 | initPrimes(&primes, &n); 20 | 21 | long start = currentTimeMillis(); 22 | int cnt = 0; 23 | int res = -1; 24 | for (;;) { 25 | res = nextPrime(&primes); 26 | cnt++; 27 | if (cnt % prntCnt == 0) { 28 | printf("Computed %d primes in %ld ms. Last one is %d\n", cnt, (currentTimeMillis() - start), res); 29 | prntCnt *= 2; 30 | } 31 | if (upto && cnt >= upto) { 32 | break; 33 | } 34 | } 35 | 36 | releasePrimes(&primes); 37 | 38 | return currentTimeMillis() - start; 39 | } 40 | 41 | int main(int argc, char** argv) { 42 | int count = -1; 43 | if (argc == 2) { 44 | count = atoi(argv[1]); 45 | } 46 | for (;;) { 47 | printf("Hundred thousand prime numbers in %ld ms\n", measure(97, 100000)); 48 | if (count != -1) { 49 | if (--count == 0) { 50 | break; 51 | } 52 | } 53 | } 54 | return (EXIT_SUCCESS); 55 | } 56 | 57 | -------------------------------------------------------------------------------- /python+ruby+js/sieve.js: -------------------------------------------------------------------------------- 1 | function Primes(natural) { 2 | this.natural = natural; 3 | this.filter = null; 4 | } 5 | Primes.prototype.next = function() { 6 | for (;;) { 7 | var n = this.natural.next(); 8 | if (this.filter === null) { 9 | var filterFactory = Polyglot.import("Filter"); 10 | this.filter = filterFactory(n); 11 | return n; 12 | } 13 | if (this.filter.acceptAndAdd(n)) { 14 | return n; 15 | } 16 | } 17 | }; 18 | 19 | function measure(prntCnt, upto) { 20 | var natural = Polyglot.import('Natural'); 21 | var primes = new Primes(natural()); 22 | 23 | var log = typeof console !== 'undefined' ? console.log : print; 24 | var start = new Date().getTime(); 25 | var cnt = 0; 26 | var res = -1; 27 | for (;;) { 28 | res = primes.next(); 29 | cnt++; 30 | if (cnt % prntCnt === 0) { 31 | log("Computed " + cnt + " primes in " + (new Date().getTime() - start) + " ms. Last one is " + res); 32 | prntCnt *= 2; 33 | } 34 | if (upto && cnt >= upto) { 35 | break; 36 | } 37 | } 38 | return new Date().getTime() - start; 39 | } 40 | 41 | for (;;) { 42 | var log = typeof console !== 'undefined' ? console.log : print; 43 | log("Hundred thousand prime numbers in " + measure(97, 100000) + " ms"); 44 | if (typeof count !== 'undefined') { 45 | if (--count) { 46 | continue; 47 | } 48 | break; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /js/fromjava/src/main/java/org/apidesign/demo/trufflejs/Main.java: -------------------------------------------------------------------------------- 1 | package org.apidesign.demo.trufflejs; 2 | 3 | import java.io.File; 4 | import java.io.FileReader; 5 | import java.net.URISyntaxException; 6 | import java.net.URL; 7 | import javax.script.ScriptEngine; 8 | import javax.script.ScriptEngineManager; 9 | 10 | final class Main { 11 | public static void main(String... args) throws Exception { 12 | File script = findSieveJs(); 13 | 14 | ScriptEngineManager sem = new ScriptEngineManager(); 15 | ScriptEngine engine = sem.getEngineByName("Graal.js"); 16 | if (engine == null) { 17 | engine = sem.getEngineByMimeType("text/javascript"); 18 | } 19 | System.err.printf("Using engine %s to run %s%n", engine.getFactory().getEngineName(), script); 20 | 21 | if (args.length == 1) { 22 | int repeat = Integer.parseInt(args[0]); 23 | engine.eval("this.count = " + repeat); 24 | } 25 | 26 | try (FileReader reader = new FileReader(script)) { 27 | engine.eval(reader); 28 | } 29 | } 30 | 31 | private static File findSieveJs() throws URISyntaxException { 32 | URL where = Main.class.getProtectionDomain().getCodeSource().getLocation(); 33 | File script = new File(where.toURI()); 34 | for (;;) { 35 | File test = new File(script, "sieve.js"); 36 | if (test.exists()) { 37 | script = test; 38 | break; 39 | } 40 | script = script.getParentFile(); 41 | } 42 | return script; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /java/algorithm/nbactions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | run 5 | 6 | package 7 | exec:java 8 | 9 | 10 | true 11 | 12 | 13 | 14 | run 15 | 16 | package 17 | exec:java 18 | 19 | 20 | 21 | debug 22 | 23 | process-classes 24 | exec:java 25 | 26 | 27 | true 28 | maven 29 | 30 | 31 | 32 | 33 | native-image 34 | 35 | 36 | run 37 | Run Native Executable 38 | 39 | exec:exec@run 40 | 41 | 42 | 43 | 44 | native-image 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /crystal/sieve.cr: -------------------------------------------------------------------------------- 1 | class Natural 2 | @cnt = 1 3 | 4 | def next 5 | @cnt += 1 6 | end 7 | end 8 | 9 | class Filter 10 | getter number 11 | property! next : Filter 12 | property! last : Filter 13 | 14 | def initialize(@number : Int32) 15 | @last = self 16 | end 17 | 18 | def accept_and_add(n) 19 | filter = self 20 | upto = Math.sqrt(n) 21 | loop do 22 | if n.divisible_by?(filter.number) 23 | return false 24 | end 25 | if filter.number > upto 26 | new_filter = Filter.new(n) 27 | last.next = new_filter 28 | @last = new_filter 29 | return true 30 | end 31 | filter = filter.next 32 | end 33 | end 34 | end 35 | 36 | class Primes 37 | @natural = Natural.new 38 | 39 | def next 40 | loop do 41 | n = @natural.next 42 | filter = @filter 43 | unless filter 44 | @filter = Filter.new(n) 45 | return n 46 | end 47 | if filter.accept_and_add(n) 48 | return n 49 | end 50 | end 51 | end 52 | 53 | def compute 54 | start = Time.now 55 | cnt = 0 56 | prnt_cnt = 97 57 | res = 0 58 | loop do 59 | res = self.next 60 | cnt += 1 61 | 62 | if cnt.divisible_by?(prnt_cnt) 63 | took = Time.now - start 64 | puts "Computed #{cnt} primes in #{took.milliseconds} ms. Last one is #{res}" 65 | prnt_cnt *= 2 66 | end 67 | break if cnt >= 100000 68 | end 69 | res 70 | end 71 | end 72 | 73 | loop do 74 | p = Primes.new 75 | time = Time.now 76 | p.compute 77 | took = Time.now - time 78 | puts "Hundred thousand primes computed in #{took.milliseconds}ms" 79 | end 80 | -------------------------------------------------------------------------------- /js/fromjava/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | org.apidesign.demo 5 | trufflejs 6 | Using ScriptEngine for Graal.js 7 | 1.0-SNAPSHOT 8 | jar 9 | 10 | UTF-8 11 | 1.8 12 | 1.8 13 | ${java.home}/bin/java 14 | -Dignore 15 | 65535 16 | 17 | 18 | 19 | 20 | org.codehaus.mojo 21 | exec-maven-plugin 22 | 1.4.0 23 | 24 | ${exec.java} 25 | 26 | ${debug} 27 | -cp 28 | 29 | org.apidesign.demo.trufflejs.Main 30 | ${repeat} 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /c/nbproject/Package-Debug.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | # 4 | # Generated - do not edit! 5 | # 6 | 7 | # Macros 8 | TOP=`pwd` 9 | CND_PLATFORM=GNU-Linux 10 | CND_CONF=Debug 11 | CND_DISTDIR=dist 12 | CND_BUILDDIR=build 13 | CND_DLIB_EXT=so 14 | NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging 15 | TMPDIRNAME=tmp-packaging 16 | OUTPUT_PATH=sieve 17 | OUTPUT_BASENAME=sieve 18 | PACKAGE_TOP_DIR=c/ 19 | 20 | # Functions 21 | function checkReturnCode 22 | { 23 | rc=$? 24 | if [ $rc != 0 ] 25 | then 26 | exit $rc 27 | fi 28 | } 29 | function makeDirectory 30 | # $1 directory path 31 | # $2 permission (optional) 32 | { 33 | mkdir -p "$1" 34 | checkReturnCode 35 | if [ "$2" != "" ] 36 | then 37 | chmod $2 "$1" 38 | checkReturnCode 39 | fi 40 | } 41 | function copyFileToTmpDir 42 | # $1 from-file path 43 | # $2 to-file path 44 | # $3 permission 45 | { 46 | cp "$1" "$2" 47 | checkReturnCode 48 | if [ "$3" != "" ] 49 | then 50 | chmod $3 "$2" 51 | checkReturnCode 52 | fi 53 | } 54 | 55 | # Setup 56 | cd "${TOP}" 57 | mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package 58 | rm -rf ${NBTMPDIR} 59 | mkdir -p ${NBTMPDIR} 60 | 61 | # Copy files and create directories and links 62 | cd "${TOP}" 63 | makeDirectory "${NBTMPDIR}/c/bin" 64 | copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 65 | 66 | 67 | # Generate tar file 68 | cd "${TOP}" 69 | rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/c.tar 70 | cd ${NBTMPDIR} 71 | tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/c.tar * 72 | checkReturnCode 73 | 74 | # Cleanup 75 | cd "${TOP}" 76 | rm -rf ${NBTMPDIR} 77 | -------------------------------------------------------------------------------- /c/nbproject/Package-Release.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | # 4 | # Generated - do not edit! 5 | # 6 | 7 | # Macros 8 | TOP=`pwd` 9 | CND_PLATFORM=GNU-Linux 10 | CND_CONF=Release 11 | CND_DISTDIR=dist 12 | CND_BUILDDIR=build 13 | CND_DLIB_EXT=so 14 | NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging 15 | TMPDIRNAME=tmp-packaging 16 | OUTPUT_PATH=sieve 17 | OUTPUT_BASENAME=sieve 18 | PACKAGE_TOP_DIR=c/ 19 | 20 | # Functions 21 | function checkReturnCode 22 | { 23 | rc=$? 24 | if [ $rc != 0 ] 25 | then 26 | exit $rc 27 | fi 28 | } 29 | function makeDirectory 30 | # $1 directory path 31 | # $2 permission (optional) 32 | { 33 | mkdir -p "$1" 34 | checkReturnCode 35 | if [ "$2" != "" ] 36 | then 37 | chmod $2 "$1" 38 | checkReturnCode 39 | fi 40 | } 41 | function copyFileToTmpDir 42 | # $1 from-file path 43 | # $2 to-file path 44 | # $3 permission 45 | { 46 | cp "$1" "$2" 47 | checkReturnCode 48 | if [ "$3" != "" ] 49 | then 50 | chmod $3 "$2" 51 | checkReturnCode 52 | fi 53 | } 54 | 55 | # Setup 56 | cd "${TOP}" 57 | mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package 58 | rm -rf ${NBTMPDIR} 59 | mkdir -p ${NBTMPDIR} 60 | 61 | # Copy files and create directories and links 62 | cd "${TOP}" 63 | makeDirectory "${NBTMPDIR}/c/bin" 64 | copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 65 | 66 | 67 | # Generate tar file 68 | cd "${TOP}" 69 | rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/c.tar 70 | cd ${NBTMPDIR} 71 | tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/c.tar * 72 | checkReturnCode 73 | 74 | # Cleanup 75 | cd "${TOP}" 76 | rm -rf ${NBTMPDIR} 77 | -------------------------------------------------------------------------------- /R/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | org.apidesign.demo 5 | sieve-r 6 | 1.0-SNAPSHOT 7 | jar 8 | Sieve with R in Java 9 | 10 | 11 | com.oracle.truffle 12 | truffle-api 13 | 0.10 14 | jar 15 | 16 | 17 | 18 | UTF-8 19 | 1.8 20 | 1.8 21 | 22 | 23 | 24 | 25 | org.codehaus.mojo 26 | exec-maven-plugin 27 | 1.4.0 28 | 29 | ${java.home}/bin/graalvm 30 | 31 | ${debug} 32 | -cp 33 | 34 | org.apidesign.demo.sieve.r.Main 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /ruby/sieve.rb: -------------------------------------------------------------------------------- 1 | class Natural 2 | def initialize 3 | @x = 1 4 | end 5 | 6 | def next 7 | @x += 1 8 | end 9 | end 10 | 11 | class Filter 12 | attr_reader :number 13 | attr_accessor :next 14 | 15 | def initialize(number) 16 | @number = number 17 | @next = nil 18 | @last = self 19 | end 20 | 21 | def acceptAndAdd(n) 22 | filter = self 23 | upto = Math.sqrt(n) 24 | while filter 25 | if n % filter.number == 0 26 | return false 27 | end 28 | if filter.number > upto 29 | break 30 | end 31 | filter = filter.next 32 | end 33 | filter = Filter.new(n) 34 | @last.next = filter 35 | @last = filter 36 | true 37 | end 38 | end 39 | 40 | class Primes 41 | def initialize(natural) 42 | @natural = natural 43 | @filter = nil 44 | end 45 | 46 | def next 47 | while true 48 | n = @natural.next 49 | if @filter == nil 50 | @filter = Filter.new(n) 51 | return n 52 | end 53 | if @filter.acceptAndAdd(n) 54 | return n 55 | end 56 | end 57 | end 58 | end 59 | 60 | def ms(start) 61 | ((Time.now - start) * 1000).floor 62 | end 63 | 64 | def fewthousands 65 | natural = Natural.new 66 | primes = Primes.new(natural) 67 | 68 | start = Time.now 69 | cnt = 0 70 | prntCnt = 97 71 | begin 72 | res = primes.next 73 | cnt += 1 74 | if cnt % prntCnt == 0 75 | puts "Computed #{cnt} primes in #{ms(start)} ms. Last one is #{res}." 76 | prntCnt = prntCnt * 2 77 | end 78 | end while cnt < 100000 79 | ms(start) 80 | end 81 | 82 | puts "Ready!" 83 | 84 | count = -1 85 | if ARGV.length == 1 86 | then 87 | count = ARGV[0].to_i 88 | end 89 | 90 | while count != 0 91 | puts "Hundred thousand prime numbers in #{fewthousands} ms" 92 | count = count - 1 93 | end 94 | -------------------------------------------------------------------------------- /erlang/sieve.erl: -------------------------------------------------------------------------------- 1 | -module(sieve). 2 | -export([mainLoop/0]). 3 | 4 | natural() -> #{ "n" => 2 }. 5 | natural(#{ "n" := N }) -> 6 | { N, #{ "n" => N + 1 } }. 7 | 8 | 9 | filterAndAdd(N, []) -> 10 | { true, [ N ] }; 11 | filterAndAdd(N, [ [H | T1 ] | T2]) -> 12 | SortedPrimes = movePrimes([H | T1], [], T2), 13 | filterAndAdd(N, SortedPrimes); 14 | filterAndAdd(N, [H | T]) when N rem H == 0 -> 15 | { false, [ H | T ] }; 16 | filterAndAdd(N, [H | T]) when N < H * H -> 17 | { true, [H | insertPrimes(N, T) ]}; 18 | filterAndAdd(N, [H | T]) -> 19 | { R, L } = filterAndAdd(N, T), 20 | { R, [ H | L ]}. 21 | 22 | insertPrimes(N, []) -> [ N ]; 23 | insertPrimes(N, [ [ H | T1] | T2 ]) -> [ [ N, H | T1 ] | T2 ]; 24 | insertPrimes(N, [ H | T2 ]) -> [ [ N ], H | T2 ]. 25 | 26 | movePrimes([], Reversed, []) -> Reversed; 27 | movePrimes(Primes, Reversed, [H | T]) -> [H | movePrimes(Primes, Reversed, T)]; 28 | movePrimes([H | T], Reversed, []) -> movePrimes(T, [ H | Reversed ], []). 29 | 30 | sieve(Iterator, Primes) -> 31 | { N, Next } = natural(Iterator), 32 | { R, NewPrimes } = filterAndAdd(N, Primes), 33 | if 34 | R -> { NewPrimes , Next }; 35 | true -> sieve(Next, Primes) 36 | end. 37 | 38 | hundredthousand() -> 39 | last(hundredthousand(100000, natural(), [])). 40 | 41 | last([ H ]) -> H; 42 | last([ [ H | T1 ] | T2 ]) -> 43 | SortedPrimes = movePrimes([H | T1], [], T2), 44 | last(SortedPrimes); 45 | last([ _ | T ]) -> last(T). 46 | 47 | hundredthousand(0, _, Primes) -> 48 | Primes; 49 | hundredthousand(Count, Iterator, Primes) -> 50 | {NewPrimes, NewIterator} = sieve(Iterator, Primes), 51 | hundredthousand(Count - 1, NewIterator, NewPrimes). 52 | 53 | mainLoop() -> 54 | Then = erlang:system_time(), 55 | Result = hundredthousand(), 56 | Now = erlang:system_time(), 57 | io:fwrite("Computed ~w in ~w ms~n", [Result, round((Now - Then) / 1000000) ]), 58 | mainLoop(). 59 | -------------------------------------------------------------------------------- /ruby+js/fromjava/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | org.apidesign.demo 5 | fromjava 6 | 1.0-SNAPSHOT 7 | jar 8 | Sieve with Ruby and JavaScript 9 | 10 | 11 | org.graalvm 12 | graal-sdk 13 | 0.33 14 | jar 15 | provided 16 | 17 | 18 | 19 | UTF-8 20 | 1.8 21 | 1.8 22 | -Dignore 23 | 65535 24 | 25 | 26 | 27 | 28 | org.codehaus.mojo 29 | exec-maven-plugin 30 | 1.4.0 31 | 32 | ${java.home}/bin/java 33 | 34 | ${debug} 35 | -cp 36 | 37 | org.apidesign.demo.rubyjs.fromjava.Main 38 | ${repeat} 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /java/client/src/main/assembly/webpages.xml: -------------------------------------------------------------------------------- 1 | 2 | 27 | 29 | 30 | webpages 31 | 32 | zip 33 | 34 | / 35 | 36 | 37 | src/main/webapp/pages 38 | / 39 | false 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /python+ruby+js/fromjava/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | org.apidesign.demo 5 | fromjava 6 | 1.0-SNAPSHOT 7 | jar 8 | Sieve with Python, Ruby and JavaScript 9 | 10 | 11 | org.graalvm.sdk 12 | graal-sdk 13 | 19.2.0.1 14 | jar 15 | provided 16 | 17 | 18 | 19 | UTF-8 20 | 1.8 21 | 1.8 22 | -Dignore 23 | 65535 24 | 25 | 26 | 27 | 28 | org.codehaus.mojo 29 | exec-maven-plugin 30 | 1.4.0 31 | 32 | ${java.home}/bin/java 33 | 34 | ${debug} 35 | -cp 36 | 37 | org.apidesign.demo.pythonrubyjs.fromjava.Main 38 | ${repeat} 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /python/sieve.py: -------------------------------------------------------------------------------- 1 | import math 2 | import time 3 | import sys 4 | 5 | class Natural: 6 | n = 2 7 | 8 | def next(self): 9 | r = self.n 10 | self.n = self.n + 1 11 | return r 12 | 13 | class Filter: 14 | def __init__(self, n): 15 | self.number = n 16 | self.next = None 17 | self.last = self 18 | 19 | def acceptAndAdd(self, n): 20 | filter = self 21 | sqrt = math.sqrt(n) 22 | while True: 23 | if n % filter.number == 0: 24 | return False 25 | if filter.number > sqrt: 26 | break 27 | filter = filter.next 28 | 29 | newFilter = Filter(n) 30 | self.last.next = newFilter 31 | self.last = newFilter 32 | return True 33 | 34 | class Primes: 35 | def __init__(self, natural): 36 | self.natural = natural 37 | self.filter = None 38 | 39 | def next(self): 40 | while True: 41 | n = self.natural.next() 42 | if (self.filter == None): 43 | self.filter = Filter(n) 44 | return n 45 | if (self.filter.acceptAndAdd(n)): 46 | return n 47 | 48 | def ms(s): 49 | ms = int(math.floor(s * 1000)) 50 | return str(ms) 51 | 52 | def measure(prntCnt, upto): 53 | primes = Primes(Natural()) 54 | start = time.time() 55 | cnt = 0 56 | res = -1 57 | while cnt < upto: 58 | res = primes.next() 59 | cnt = cnt + 1 60 | if (cnt % prntCnt == 0): 61 | took = time.time() - start 62 | print("Computed " + str(cnt) + " primes in " + ms(took) + " ms. Last one is " + str(res)) 63 | prntCnt = prntCnt * 2 64 | 65 | return time.time() - start 66 | 67 | count = -1 68 | if len(sys.argv) > 1: 69 | count = int(float(sys.argv[1])) 70 | while count != 0: 71 | took= measure(97, 100000) 72 | print("Hundred thousand prime numbers in " + ms(took) + " ms") 73 | count = count - 1 74 | -------------------------------------------------------------------------------- /java/algorithm/src/main/java/org/apidesign/demo/sieve/eratosthenes/Primes.java: -------------------------------------------------------------------------------- 1 | package org.apidesign.demo.sieve.eratosthenes; 2 | 3 | public abstract class Primes { 4 | private final Natural natural; 5 | private Filter filter; 6 | 7 | protected Primes() { 8 | this.natural = new Natural(); 9 | } 10 | 11 | int next() { 12 | for (;;) { 13 | int n = natural.next(); 14 | if (filter == null) { 15 | filter = new Filter(n); 16 | return n; 17 | } 18 | if (filter.acceptAndAdd(n)) { 19 | return n; 20 | } 21 | } 22 | } 23 | 24 | protected abstract void log(String msg); 25 | 26 | public final int compute() { 27 | long start = System.currentTimeMillis(); 28 | int cnt = 0; 29 | int prntCnt = 97; 30 | int res; 31 | for (;;) { 32 | res = next(); 33 | cnt += 1; 34 | if (cnt % prntCnt == 0) { 35 | log("Computed " + cnt + " primes in " + (System.currentTimeMillis() - start) + " ms. Last one is " + res); 36 | prntCnt *= 2; 37 | } 38 | if (cnt >= 100000) { 39 | break; 40 | } 41 | } 42 | return res; 43 | } 44 | 45 | public static void main(String... args) { 46 | int cnt = Integer.MAX_VALUE; 47 | if (args.length == 1) { 48 | cnt = Integer.parseInt(args[0]); 49 | } 50 | while (cnt-- > 0) { 51 | Primes p = new Primes() { 52 | @Override 53 | protected void log(String msg) { 54 | System.out.println(msg); 55 | } 56 | }; 57 | long start = System.currentTimeMillis(); 58 | int value = p.compute(); 59 | long took = System.currentTimeMillis() - start; 60 | System.out.println("Hundred thousand primes computed in " + took + " ms"); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ruby+js/sieve.js: -------------------------------------------------------------------------------- 1 | function Filter(number) { 2 | this.number = number; 3 | this.next = null; 4 | this.last = this; 5 | } 6 | Filter.prototype.acceptAndAdd = function(n) { 7 | var filter = this; 8 | var sqrt = Math.sqrt(n); 9 | for (;;) { 10 | if (n % filter.number === 0) { 11 | return false; 12 | } 13 | if (filter.number > sqrt) { 14 | break; 15 | } 16 | filter = filter.next; 17 | } 18 | var newFilter = new Filter(n); 19 | this.last.next = newFilter; 20 | this.last = newFilter; 21 | return true; 22 | }; 23 | 24 | function Primes(natural) { 25 | this.natural = natural; 26 | this.filter = null; 27 | } 28 | Primes.prototype.next = function() { 29 | for (;;) { 30 | var n = this.natural.next(); 31 | if (this.filter === null) { 32 | this.filter = new Filter(n); 33 | return n; 34 | } 35 | if (this.filter.acceptAndAdd(n)) { 36 | return n; 37 | } 38 | } 39 | }; 40 | 41 | function measure(prntCnt, upto) { 42 | var natural = Polyglot.import('Natural'); 43 | var primes = new Primes(natural()); 44 | 45 | var log = typeof console !== 'undefined' ? console.log : print; 46 | var start = new Date().getTime(); 47 | var cnt = 0; 48 | var res = -1; 49 | for (;;) { 50 | res = primes.next(); 51 | cnt++; 52 | if (cnt % prntCnt === 0) { 53 | log("Computed " + cnt + " primes in " + (new Date().getTime() - start) + " ms. Last one is " + res); 54 | prntCnt *= 2; 55 | } 56 | if (upto && cnt >= upto) { 57 | break; 58 | } 59 | } 60 | return new Date().getTime() - start; 61 | } 62 | 63 | for (;;) { 64 | var log = typeof console !== 'undefined' ? console.log : print; 65 | log("Hundred thousand prime numbers in " + measure(97, 100000) + " ms"); 66 | if (typeof count !== 'undefined') { 67 | if (--count) { 68 | continue; 69 | } 70 | break; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /R+js/sieve.js: -------------------------------------------------------------------------------- 1 | function Filter(number) { 2 | this.number = number; 3 | this.next = null; 4 | this.last = this; 5 | } 6 | Filter.prototype.acceptAndAdd = function(n) { 7 | var filter = this; 8 | var sqrt = Math.sqrt(n); 9 | for (;;) { 10 | if (n % filter.number === 0) { 11 | return false; 12 | } 13 | if (filter.number > sqrt) { 14 | break; 15 | } 16 | filter = filter.next; 17 | } 18 | var newFilter = new Filter(n); 19 | this.last.next = newFilter; 20 | this.last = newFilter; 21 | return true; 22 | }; 23 | 24 | function Primes(natural) { 25 | this.natural = natural; 26 | this.at = 0; 27 | this.filter = null; 28 | } 29 | Primes.prototype.next = function() { 30 | for (;;) { 31 | var n = this.natural[this.at++]; 32 | if (this.filter === null) { 33 | this.filter = new Filter(n); 34 | return n; 35 | } 36 | if (this.filter.acceptAndAdd(n)) { 37 | return n; 38 | } 39 | } 40 | }; 41 | 42 | function measure(prntCnt, upto) { 43 | var natural = Polyglot.import('Natural'); 44 | var primes = new Primes(natural()); 45 | 46 | var log = typeof console !== 'undefined' ? console.log : print; 47 | var start = new Date().getTime(); 48 | var cnt = 0; 49 | var res = -1; 50 | for (;;) { 51 | res = primes.next(); 52 | cnt++; 53 | if (cnt % prntCnt === 0) { 54 | log("Computed " + cnt + " primes in " + (new Date().getTime() - start) + " ms. Last one is " + res); 55 | prntCnt *= 2; 56 | } 57 | if (upto && cnt >= upto) { 58 | break; 59 | } 60 | } 61 | return new Date().getTime() - start; 62 | } 63 | 64 | var count; 65 | for (;;) { 66 | if (typeof count !== 'undefined') { 67 | if (!count--) { 68 | break; 69 | } 70 | } 71 | var log = typeof console !== 'undefined' ? console.log : print; 72 | log("Hundred thousand prime numbers in " + measure(97, 100000) + " ms"); 73 | } 74 | -------------------------------------------------------------------------------- /go/sieve.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | "time" 9 | ) 10 | 11 | func natural() func() int { 12 | i := 1 13 | return func() int { 14 | i++ 15 | return i 16 | } 17 | } 18 | 19 | type Filter struct { 20 | number int 21 | next* Filter 22 | last* Filter 23 | } 24 | 25 | func (this *Filter) acceptAndAdd(n int) bool { 26 | filter := this; 27 | sqrt := int(math.Sqrt(float64(n))); 28 | for { 29 | if n % filter.number == 0 { 30 | return false; 31 | } 32 | if filter.number > sqrt { 33 | break; 34 | } 35 | filter = filter.next; 36 | } 37 | newFilter := &Filter{ n, nil, nil } 38 | this.last.next = newFilter 39 | this.last = newFilter 40 | return true 41 | } 42 | 43 | type Primes struct { 44 | natural func() int 45 | filter *Filter 46 | } 47 | 48 | func primes(natural func() int) Primes { 49 | return Primes{ natural, nil } 50 | } 51 | 52 | func (this *Primes) next() int { 53 | for { 54 | n := this.natural(); 55 | if (this.filter == nil) { 56 | this.filter = &Filter{ n, nil, nil } 57 | this.filter.last = this.filter 58 | return n; 59 | } 60 | if (this.filter.acceptAndAdd(n)) { 61 | return n; 62 | } 63 | } 64 | }; 65 | 66 | 67 | func measure(prntCnt int, upto int) int64 { 68 | primes := primes(natural()); 69 | 70 | start := time.Now().UnixNano() / int64(time.Millisecond) 71 | cnt := 0; 72 | for { 73 | res := primes.next(); 74 | cnt++; 75 | if (cnt % prntCnt == 0) { 76 | now := time.Now().UnixNano() / int64(time.Millisecond) 77 | took := now - start 78 | fmt.Printf("Computed %d primes in %d ms. Last one is %d\n", cnt, took, res) 79 | prntCnt *= 2 80 | } 81 | if (cnt >= upto) { 82 | break 83 | } 84 | } 85 | now := time.Now().UnixNano() / int64(time.Millisecond) 86 | return now - start 87 | } 88 | 89 | 90 | func main() { 91 | for { 92 | fmt.Printf("Hundred thousand prime numbers in %d ms\n", measure(97, 100000)) 93 | } 94 | } 95 | 96 | -------------------------------------------------------------------------------- /.test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | set -e 4 | 5 | if ! [ -e $1/bin/java ]; then 6 | echo Usage: $0 "" 7 | exit 1 8 | fi 9 | 10 | GRAALBIN=$1/bin 11 | 12 | function ginstall() { 13 | if [ -e $GRAALBIN/gu ]; then 14 | if $GRAALBIN/gu list | grep "^$1 "; then 15 | echo $1 is installed 16 | else 17 | $GRAALBIN/gu install $1 18 | REBUILD=true 19 | fi 20 | fi 21 | } 22 | 23 | echo -en 'travis_fold:start:c\\r' 24 | make -C c 25 | ./c/sieve 25 26 | 27 | (cd c; clang -c -emit-llvm *.c) 28 | $GRAALBIN/lli --lib c/natural.bc --lib c/filter.bc --lib c/primes.bc c/main.bc 25 29 | echo -en 'travis_fold:end:c\\r' 30 | 31 | echo -en 'travis_fold:start:java\\r' 32 | mvn -q -f java/pom.xml clean install 33 | mvn -q -f java/algorithm/pom.xml exec:java -Drepeat=25 34 | JAVA_HOME=$1 mvn -q -f java/algorithm/pom.xml exec:java -Drepeat=25 35 | if [ "x" != "x$DISPLAY" ]; then 36 | mvn -q -f java/client/pom.xml exec:exec -Drepeat=5 37 | fi 38 | echo -en 'travis_fold:end:java\\r' 39 | 40 | echo -en 'travis_fold:start:R\\r' 41 | ginstall R 42 | $GRAALBIN/polyglot --jvm --eval "js:count=25" --file R+js/sieve.R --file R+js/sieve.js 43 | echo -en 'travis_fold:end:R\\r' 44 | 45 | echo -en 'travis_fold:start:ruby\\r' 46 | ginstall ruby 47 | JAVA_HOME=$1 mvn -q clean package exec:exec -f ruby+js/fromjava/pom.xml -Drepeat=25 48 | $GRAALBIN/ruby ruby/sieve.rb 25 49 | echo -en 'travis_fold:end:ruby\\r' 50 | 51 | echo -en 'travis_fold:start:js\\r' 52 | if ! [ -f $GRAALBIN/node ]; then 53 | ginstall nodejs 54 | fi 55 | $GRAALBIN/node js/sieve.js 15 56 | mvn -q -f js/fromjava/pom.xml package exec:exec -Drepeat=15 57 | JAVA_HOME=$1 mvn -q -f js/fromjava/pom.xml package exec:exec -Drepeat=15 58 | echo -en 'travis_fold:end:js\\r' 59 | 60 | echo -en 'travis_fold:start:python\\r' 61 | ginstall python 62 | $GRAALBIN/graalpython python/sieve.py 15 63 | echo -en 'travis_fold:end:python\\r' 64 | 65 | echo -en 'travis_fold:start:polyglot\\r' 66 | $GRAALBIN/polyglot --jvm --file ruby+js/sieve.rb --eval js:count=15 --file ruby+js/sieve.js 67 | if [ -n "$REBUILD" ]; then 68 | ginstall native-image 69 | $GRAALBIN/gu rebuild-images polyglot 70 | fi 71 | if $GRAALBIN/polyglot --version:graalvm | grep -i Ruby; then 72 | $GRAALBIN/polyglot --file ruby+js/sieve.rb --eval js:count=15 --file ruby+js/sieve.js 73 | fi 74 | echo -en 'travis_fold:end:polyglot\\r' 75 | -------------------------------------------------------------------------------- /java/client-web/nbactions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | run 5 | 6 | jar 7 | 8 | 9 | package 10 | bck2brwsr:show 11 | 12 | 13 | true 14 | 15 | 16 | 17 | debug 18 | 19 | jar 20 | 21 | 22 | package 23 | bck2brwsr:show 24 | 25 | 26 | true 27 | true 28 | 29 | 30 | 31 | CUSTOM-teavm-show 32 | Run in a Browser via TeaVM 33 | 34 | clean 35 | package 36 | bck2brwsr:show 37 | 38 | 39 | true 40 | 41 | 42 | teavm 43 | 44 | 45 | 46 | CUSTOM-teavm-show 47 | Debug in a Browser via TeaVM 48 | 49 | clean 50 | package 51 | bck2brwsr:show 52 | 53 | 54 | true 55 | true 56 | 57 | 58 | teavm 59 | 60 | 61 | 62 | CUSTOM-teavm-web 63 | Package for website via TeaVM 64 | 65 | clean 66 | package 67 | 68 | 69 | teavm 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /c/nbproject/Makefile-Debug.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Generated Makefile - do not edit! 3 | # 4 | # Edit the Makefile in the project folder instead (../Makefile). Each target 5 | # has a -pre and a -post target defined where you can add customized code. 6 | # 7 | # This makefile implements configuration specific macros and targets. 8 | 9 | 10 | # Environment 11 | MKDIR=mkdir 12 | CP=cp 13 | GREP=grep 14 | NM=nm 15 | CCADMIN=CCadmin 16 | RANLIB=ranlib 17 | CC=gcc 18 | CCC=g++ 19 | CXX=g++ 20 | FC=gfortran 21 | AS=as 22 | 23 | # Macros 24 | CND_PLATFORM=GNU-Linux 25 | CND_DLIB_EXT=so 26 | CND_CONF=Debug 27 | CND_DISTDIR=dist 28 | CND_BUILDDIR=build 29 | 30 | # Include project Makefile 31 | include Makefile 32 | 33 | # Object Directory 34 | OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} 35 | 36 | # Object Files 37 | OBJECTFILES= \ 38 | ${OBJECTDIR}/filter.o \ 39 | ${OBJECTDIR}/main.o \ 40 | ${OBJECTDIR}/natural.o \ 41 | ${OBJECTDIR}/primes.o 42 | 43 | 44 | # C Compiler Flags 45 | CFLAGS= 46 | 47 | # CC Compiler Flags 48 | CCFLAGS= 49 | CXXFLAGS= 50 | 51 | # Fortran Compiler Flags 52 | FFLAGS= 53 | 54 | # Assembler Flags 55 | ASFLAGS= 56 | 57 | # Link Libraries and Options 58 | LDLIBSOPTIONS=-lm 59 | 60 | # Build Targets 61 | .build-conf: ${BUILD_SUBPROJECTS} 62 | "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk sieve 63 | 64 | sieve: ${OBJECTFILES} 65 | ${LINK.c} -o sieve ${OBJECTFILES} ${LDLIBSOPTIONS} 66 | 67 | ${OBJECTDIR}/filter.o: filter.c 68 | ${MKDIR} -p ${OBJECTDIR} 69 | ${RM} "$@.d" 70 | $(COMPILE.c) -g -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/filter.o filter.c 71 | 72 | ${OBJECTDIR}/main.o: main.c 73 | ${MKDIR} -p ${OBJECTDIR} 74 | ${RM} "$@.d" 75 | $(COMPILE.c) -g -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/main.o main.c 76 | 77 | ${OBJECTDIR}/natural.o: natural.c 78 | ${MKDIR} -p ${OBJECTDIR} 79 | ${RM} "$@.d" 80 | $(COMPILE.c) -g -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/natural.o natural.c 81 | 82 | ${OBJECTDIR}/primes.o: primes.c 83 | ${MKDIR} -p ${OBJECTDIR} 84 | ${RM} "$@.d" 85 | $(COMPILE.c) -g -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/primes.o primes.c 86 | 87 | # Subprojects 88 | .build-subprojects: 89 | 90 | # Clean Targets 91 | .clean-conf: ${CLEAN_SUBPROJECTS} 92 | ${RM} -r ${CND_BUILDDIR}/${CND_CONF} 93 | 94 | # Subprojects 95 | .clean-subprojects: 96 | 97 | # Enable dependency checking 98 | .dep.inc: .depcheck-impl 99 | 100 | include .dep.inc 101 | -------------------------------------------------------------------------------- /c/nbproject/Makefile-Release.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Generated Makefile - do not edit! 3 | # 4 | # Edit the Makefile in the project folder instead (../Makefile). Each target 5 | # has a -pre and a -post target defined where you can add customized code. 6 | # 7 | # This makefile implements configuration specific macros and targets. 8 | 9 | 10 | # Environment 11 | MKDIR=mkdir 12 | CP=cp 13 | GREP=grep 14 | NM=nm 15 | CCADMIN=CCadmin 16 | RANLIB=ranlib 17 | CC=gcc 18 | CCC=g++ 19 | CXX=g++ 20 | FC=gfortran 21 | AS=as 22 | 23 | # Macros 24 | CND_PLATFORM=GNU-Linux 25 | CND_DLIB_EXT=so 26 | CND_CONF=Release 27 | CND_DISTDIR=dist 28 | CND_BUILDDIR=build 29 | 30 | # Include project Makefile 31 | include Makefile 32 | 33 | # Object Directory 34 | OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} 35 | 36 | # Object Files 37 | OBJECTFILES= \ 38 | ${OBJECTDIR}/filter.o \ 39 | ${OBJECTDIR}/main.o \ 40 | ${OBJECTDIR}/natural.o \ 41 | ${OBJECTDIR}/primes.o 42 | 43 | 44 | # C Compiler Flags 45 | CFLAGS= 46 | 47 | # CC Compiler Flags 48 | CCFLAGS= 49 | CXXFLAGS= 50 | 51 | # Fortran Compiler Flags 52 | FFLAGS= 53 | 54 | # Assembler Flags 55 | ASFLAGS= 56 | 57 | # Link Libraries and Options 58 | LDLIBSOPTIONS=-lm 59 | 60 | # Build Targets 61 | .build-conf: ${BUILD_SUBPROJECTS} 62 | "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk sieve 63 | 64 | sieve: ${OBJECTFILES} 65 | ${LINK.c} -o sieve ${OBJECTFILES} ${LDLIBSOPTIONS} 66 | 67 | ${OBJECTDIR}/filter.o: filter.c 68 | ${MKDIR} -p ${OBJECTDIR} 69 | ${RM} "$@.d" 70 | $(COMPILE.c) -O2 -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/filter.o filter.c 71 | 72 | ${OBJECTDIR}/main.o: main.c 73 | ${MKDIR} -p ${OBJECTDIR} 74 | ${RM} "$@.d" 75 | $(COMPILE.c) -O2 -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/main.o main.c 76 | 77 | ${OBJECTDIR}/natural.o: natural.c 78 | ${MKDIR} -p ${OBJECTDIR} 79 | ${RM} "$@.d" 80 | $(COMPILE.c) -O2 -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/natural.o natural.c 81 | 82 | ${OBJECTDIR}/primes.o: primes.c 83 | ${MKDIR} -p ${OBJECTDIR} 84 | ${RM} "$@.d" 85 | $(COMPILE.c) -O2 -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/primes.o primes.c 86 | 87 | # Subprojects 88 | .build-subprojects: 89 | 90 | # Clean Targets 91 | .clean-conf: ${CLEAN_SUBPROJECTS} 92 | ${RM} -r ${CND_BUILDDIR}/${CND_CONF} 93 | 94 | # Subprojects 95 | .clean-subprojects: 96 | 97 | # Enable dependency checking 98 | .dep.inc: .depcheck-impl 99 | 100 | include .dep.inc 101 | -------------------------------------------------------------------------------- /java/client-web/src/main/assembly/teavm.xml: -------------------------------------------------------------------------------- 1 | 2 | 27 | 29 | 30 | teavm 31 | 32 | zip 33 | dir 34 | 35 | public_html 36 | 37 | 38 | target/web/pages 39 | / 40 | 41 | index.html 42 | 43 | 44 | 45 | target/web/pages 46 | / 47 | true 48 | 49 | index.html 50 | 51 | 52 | 53 | ${project.build.directory}/teavm/ 54 | / 55 | false 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.apidesign.demo 7 | sieve-pom 8 | 1.0-SNAPSHOT 9 | pom 10 | Sieve of Eratosthenes in Java 11 | 12 | client 13 | client-web 14 | algorithm 15 | 16 | 17 | 1.6 18 | 0.30 19 | 1.0 20 | 1.0 21 | FULL 22 | 2.13 23 | UTF-8 24 | 25 | 26 | 27 | 28 | org.testng 29 | testng 30 | test 31 | 6.8.8 32 | 33 | 34 | com.dukescript.api 35 | junit-osgi 36 | test 37 | 4.12 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-enforcer-plugin 46 | 1.3.1 47 | 48 | 49 | enforce-versions 50 | 51 | enforce 52 | 53 | 54 | 55 | 56 | 57 | false 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /js/sieve.js: -------------------------------------------------------------------------------- 1 | function Natural() { 2 | this.x = 2; 3 | }; 4 | Natural.prototype.next = function() { 5 | return this.x++; 6 | }; 7 | 8 | function Filter(number) { 9 | this.number = number; 10 | this.next = null; 11 | this.last = this; 12 | } 13 | Filter.prototype.acceptAndAdd = function(n) { 14 | var filter = this; 15 | var sqrt = Math.sqrt(n); 16 | for (;;) { 17 | if (n % filter.number === 0) { 18 | return false; 19 | } 20 | if (filter.number > sqrt) { 21 | break; 22 | } 23 | filter = filter.next; 24 | } 25 | var newFilter = new Filter(n); 26 | this.last.next = newFilter; 27 | this.last = newFilter; 28 | return true; 29 | }; 30 | 31 | function Primes(natural) { 32 | this.natural = natural; 33 | this.filter = null; 34 | } 35 | Primes.prototype.next = function() { 36 | for (;;) { 37 | var n = this.natural.next(); 38 | if (this.filter === null) { 39 | this.filter = new Filter(n); 40 | return n; 41 | } 42 | if (this.filter.acceptAndAdd(n)) { 43 | return n; 44 | } 45 | } 46 | }; 47 | 48 | function measure(prntCnt, upto) { 49 | var primes = new Primes(new Natural()); 50 | 51 | var start = new Date().getTime(); 52 | var cnt = 0; 53 | var res = -1; 54 | for (;;) { 55 | res = primes.next(); 56 | cnt++; 57 | if (cnt % prntCnt === 0) { 58 | log("Computed " + cnt + " primes in " + (new Date().getTime() - start) + " ms. Last one is " + res); 59 | prntCnt *= 2; 60 | } 61 | if (upto && cnt >= upto) { 62 | break; 63 | } 64 | } 65 | return new Date().getTime() - start; 66 | } 67 | 68 | var log = typeof console !== 'undefined' ? console.log : ( 69 | typeof println !== 'undefined' ? println : print 70 | ); 71 | if (typeof count === 'undefined') { 72 | var count = 256 * 256; 73 | if (typeof process !== 'undefined' && process.argv.length === 3) { 74 | count = new Number(process.argv[2]); 75 | } 76 | } 77 | if (typeof setTimeout === 'undefined') { 78 | var pending = []; 79 | setTimeout = function(r) { 80 | var process = pending.length === 0; 81 | pending.push(r); 82 | if (process) { 83 | while (pending.length > 0) { 84 | pending[0](); 85 | pending.shift(); 86 | } 87 | } 88 | }; 89 | } 90 | 91 | function oneRound() { 92 | log("Hundred thousand prime numbers in " + measure(97, 100000) + " ms"); 93 | if (count-- > 0) { 94 | setTimeout(oneRound, 50); 95 | } 96 | } 97 | setTimeout(oneRound, 50); 98 | -------------------------------------------------------------------------------- /java/client-web/src/main/assembly/bck2brwsr.xml: -------------------------------------------------------------------------------- 1 | 2 | 27 | 29 | 30 | bck2brwsr 31 | 32 | zip 33 | dir 34 | 35 | public_html 36 | 37 | 38 | target/web/pages 39 | / 40 | 41 | index.html 42 | 43 | 44 | 45 | target/web/pages 46 | / 47 | true 48 | 49 | index.html 50 | 51 | 52 | 53 | ${project.build.directory} 54 | / 55 | 56 | *.js 57 | lib/*.js 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /ruby+js/fromjava/src/main/java/org/apidesign/demo/rubyjs/fromjava/Main.java: -------------------------------------------------------------------------------- 1 | package org.apidesign.demo.rubyjs.fromjava; 2 | 3 | import java.io.File; 4 | import java.net.URISyntaxException; 5 | import java.net.URL; 6 | import org.graalvm.polyglot.Context; 7 | import org.graalvm.polyglot.Source; 8 | 9 | public final class Main { 10 | private static void execute(Integer repeat) throws Exception { 11 | // executing ruby currently requires all access flag to be set. 12 | Context vm = Context.newBuilder().allowAllAccess(true).build(); 13 | 14 | if (repeat != null) { 15 | vm.eval("js", "count=" + repeat); 16 | } 17 | 18 | File scriptDir = findScriptDir(); 19 | Source ruby = Source.newBuilder("ruby", new File(scriptDir, "sieve.rb")).build(); 20 | Source js = Source.newBuilder("js", new File(scriptDir, "sieve.js")).build(); 21 | 22 | vm.eval(ruby); 23 | vm.eval(js); 24 | } 25 | 26 | private Main() { 27 | } 28 | 29 | public static void main(String[] args) throws Exception { 30 | prologAndEpilog(true); 31 | System.err.println("Setting up PolyglotEngine"); 32 | try { 33 | Integer count = null; 34 | if (args.length == 1) { 35 | count = Integer.parseInt(args[0]); 36 | } 37 | execute(count); 38 | } catch (Throwable err) { 39 | System.err.println("Initialization problem " + err.getClass().getName() + ": " + err.getMessage()); 40 | System.err.println("Are you running on GraalVM?"); 41 | System.err.println("Download from OTN: http://www.oracle.com/technetwork/oracle-labs/program-languages/overview/index.html"); 42 | prologAndEpilog(false); 43 | System.exit(1); 44 | } 45 | } 46 | 47 | private static void prologAndEpilog(boolean prolog) { 48 | if (!prolog) { 49 | System.err.println("*********************************"); 50 | } 51 | System.err.println(); 52 | System.err.println(); 53 | System.err.println(); 54 | System.err.println(); 55 | if (prolog) { 56 | System.err.println("*********************************"); 57 | } 58 | } 59 | 60 | private static File findScriptDir() throws URISyntaxException { 61 | URL url = Main.class.getProtectionDomain().getCodeSource().getLocation(); 62 | File local = new File(url.toURI()); 63 | for (;;) { 64 | File sieveInRuby = new File(local, "sieve.rb"); 65 | if (sieveInRuby.exists()) { 66 | break; 67 | } 68 | local = local.getParentFile(); 69 | } 70 | return local; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /python+ruby+js/fromjava/src/main/java/org/apidesign/demo/pythonrubyjs/fromjava/Main.java: -------------------------------------------------------------------------------- 1 | package org.apidesign.demo.pythonrubyjs.fromjava; 2 | 3 | import java.io.File; 4 | import java.net.URISyntaxException; 5 | import java.net.URL; 6 | import org.graalvm.polyglot.Context; 7 | import org.graalvm.polyglot.Source; 8 | 9 | public final class Main { 10 | private static void execute(Integer repeat) throws Exception { 11 | // executing ruby currently requires all access flag to be set. 12 | Context vm = Context.newBuilder().allowAllAccess(true).build(); 13 | 14 | if (repeat != null) { 15 | vm.eval("js", "count=" + repeat); 16 | } 17 | 18 | File scriptDir = findScriptDir(); 19 | Source python = Source.newBuilder("python", new File(scriptDir, "sieve.py")).build(); 20 | Source ruby = Source.newBuilder("ruby", new File(scriptDir, "sieve.rb")).build(); 21 | Source js = Source.newBuilder("js", new File(scriptDir, "sieve.js")).build(); 22 | 23 | vm.eval(python); 24 | vm.eval(ruby); 25 | vm.eval(js); 26 | } 27 | 28 | private Main() { 29 | } 30 | 31 | public static void main(String[] args) throws Exception { 32 | prologAndEpilog(true); 33 | System.err.println("Setting up PolyglotEngine"); 34 | try { 35 | Integer count = null; 36 | if (args.length == 1) { 37 | count = Integer.parseInt(args[0]); 38 | } 39 | execute(count); 40 | } catch (Throwable err) { 41 | System.err.println("Initialization problem " + err.getClass().getName() + ": " + err.getMessage()); 42 | System.err.println("Are you running on GraalVM?"); 43 | System.err.println("Download from OTN: http://www.oracle.com/technetwork/oracle-labs/program-languages/overview/index.html"); 44 | prologAndEpilog(false); 45 | System.exit(1); 46 | } 47 | } 48 | 49 | private static void prologAndEpilog(boolean prolog) { 50 | if (!prolog) { 51 | System.err.println("*********************************"); 52 | } 53 | System.err.println(); 54 | System.err.println(); 55 | System.err.println(); 56 | System.err.println(); 57 | if (prolog) { 58 | System.err.println("*********************************"); 59 | } 60 | } 61 | 62 | private static File findScriptDir() throws URISyntaxException { 63 | URL url = Main.class.getProtectionDomain().getCodeSource().getLocation(); 64 | File local = new File(url.toURI()); 65 | for (;;) { 66 | File sieveInRuby = new File(local, "sieve.rb"); 67 | if (sieveInRuby.exists()) { 68 | break; 69 | } 70 | local = local.getParentFile(); 71 | } 72 | return local; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /R+js/fromjava/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | org.apidesign.demo 5 | fromjava 6 | 1.0-SNAPSHOT 7 | jar 8 | Sieve with R and JavaScript 9 | 10 | 11 | com.oracle.truffle 12 | truffle-api 13 | 0.10 14 | jar 15 | 16 | 17 | 18 | UTF-8 19 | 1.8 20 | 1.8 21 | -Dignore 22 | -Dignore 23 | 24 | 25 | 26 | 27 | org.codehaus.mojo 28 | exec-maven-plugin 29 | 1.4.0 30 | 31 | ${graalvm}/bin/java 32 | 33 | ${debug} 34 | ${polyglot} 35 | -cp 36 | 37 | org.apidesign.demo.rjs.fromjava.Main 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | graalvm-pre-0.20 46 | 47 | 48 | ${java.home}/bin/graalvm 49 | 50 | 51 | 52 | ${java.home} 53 | -polyglot 54 | 55 | 56 | 57 | one-level-up 58 | 59 | 60 | ${java.home}/../bin/graalvm 61 | 62 | 63 | 64 | ${java.home}/../ 65 | 66 | 67 | 68 | graalvm-0.20 69 | 70 | 71 | ${java.home}/../../bin/graalvm 72 | 73 | 74 | 75 | ${java.home}/../../ 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /lua/sieve.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local clock = os.clock 4 | local log = io.write -- this is faster than print() on LuaJIT 5 | local sqrt = math.sqrt 6 | 7 | 8 | --- Returns CPU time in miliseconds. 9 | -- 10 | -- NOTE: LuaJIT cannot optimize os.clock function. Maybe we can achieve 11 | -- better performance with some FFI based implementation of timer. 12 | local function cpu_time () 13 | return clock() * 1000 -- to ms 14 | end 15 | 16 | 17 | local function naturals_gen (_, i) 18 | return (i or 1) + 1 19 | end 20 | 21 | --- Returns an iterator that generates natural numbers starting with `init`. 22 | local function naturals (init) 23 | return naturals_gen, nil, init 24 | end 25 | 26 | 27 | local LinkedList = {} 28 | LinkedList.__index = LinkedList 29 | 30 | --- Creates a new linked list. 31 | function LinkedList.new () 32 | return setmetatable({}, LinkedList) 33 | end 34 | 35 | --- Inserts the given `value` to the end of the list. 36 | function LinkedList:push (value) 37 | local node = { value = value } 38 | 39 | if self.last then 40 | self.last.next = node 41 | else 42 | self.first = node 43 | end 44 | 45 | self.last = node 46 | end 47 | 48 | local function list_iter_gen (list, node) 49 | if node then 50 | node = node.next 51 | else 52 | node = list.first 53 | end 54 | 55 | return node, node.value 56 | end 57 | 58 | --- Returns an iterator that iterates over nodes of the list. 59 | function LinkedList:iter () 60 | return list_iter_gen, self, nil 61 | end 62 | 63 | 64 | --- Returns true if the given `num` is a prime number. 65 | -- 66 | -- @tparam int num The number to test. 67 | -- @tparam table found_primes Linked list of the already found primes. 68 | local function is_prime (num, found_primes) 69 | local num_sqrt = sqrt(num) 70 | 71 | for _, prime in found_primes:iter() do 72 | if num % prime == 0 then 73 | return false 74 | end 75 | if prime > num_sqrt then 76 | return true 77 | end 78 | end 79 | 80 | return true 81 | end 82 | 83 | --- Returns next prime number. 84 | -- 85 | -- @tparam table found_primes Linked list of the already found primes. 86 | -- @tparam int|nil last_prime 87 | local function find_primes_gen (found_primes, last_prime) 88 | for n in naturals(last_prime) do 89 | if last_prime == nil or is_prime(n, found_primes) then 90 | found_primes:push(n) 91 | return n 92 | end 93 | end 94 | end 95 | 96 | --- Returns an iterator that generates prime numbers. 97 | local function find_primes () 98 | return find_primes_gen, LinkedList.new(), nil 99 | end 100 | 101 | 102 | local function measure (print_cnt, upto) 103 | local cnt = 1 104 | local start_time = cpu_time() 105 | 106 | for prime in find_primes() do 107 | cnt = cnt + 1 108 | 109 | if cnt % print_cnt == 0 then 110 | log('Computed ', cnt, ' primes in ', cpu_time() - start_time, 111 | ' ms. Last one is ', prime, '\n') 112 | print_cnt = print_cnt * 2 113 | end 114 | 115 | if cnt >= upto then 116 | return cpu_time() - start_time 117 | end 118 | end 119 | end 120 | 121 | 122 | while true do 123 | local duration = measure(97, 100000) 124 | log('Hundred thousand prime numbers in ', duration, ' ms\n----\n') 125 | end 126 | -------------------------------------------------------------------------------- /c/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # There exist several targets which are by default empty and which can be 3 | # used for execution of your targets. These targets are usually executed 4 | # before and after some main targets. They are: 5 | # 6 | # .build-pre: called before 'build' target 7 | # .build-post: called after 'build' target 8 | # .clean-pre: called before 'clean' target 9 | # .clean-post: called after 'clean' target 10 | # .clobber-pre: called before 'clobber' target 11 | # .clobber-post: called after 'clobber' target 12 | # .all-pre: called before 'all' target 13 | # .all-post: called after 'all' target 14 | # .help-pre: called before 'help' target 15 | # .help-post: called after 'help' target 16 | # 17 | # Targets beginning with '.' are not intended to be called on their own. 18 | # 19 | # Main targets can be executed directly, and they are: 20 | # 21 | # build build a specific configuration 22 | # clean remove built files from a configuration 23 | # clobber remove all built files 24 | # all build all configurations 25 | # help print help mesage 26 | # 27 | # Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and 28 | # .help-impl are implemented in nbproject/makefile-impl.mk. 29 | # 30 | # Available make variables: 31 | # 32 | # CND_BASEDIR base directory for relative paths 33 | # CND_DISTDIR default top distribution directory (build artifacts) 34 | # CND_BUILDDIR default top build directory (object files, ...) 35 | # CONF name of current configuration 36 | # CND_PLATFORM_${CONF} platform name (current configuration) 37 | # CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) 38 | # CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) 39 | # CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) 40 | # CND_PACKAGE_DIR_${CONF} directory of package (current configuration) 41 | # CND_PACKAGE_NAME_${CONF} name of package (current configuration) 42 | # CND_PACKAGE_PATH_${CONF} path to package (current configuration) 43 | # 44 | # NOCDDL 45 | 46 | 47 | # Environment 48 | MKDIR=mkdir 49 | CP=cp 50 | CCADMIN=CCadmin 51 | 52 | 53 | # build 54 | build: .build-post 55 | 56 | .build-pre: 57 | # Add your pre 'build' code here... 58 | 59 | .build-post: .build-impl 60 | # Add your post 'build' code here... 61 | 62 | 63 | # clean 64 | clean: .clean-post 65 | 66 | .clean-pre: 67 | # Add your pre 'clean' code here... 68 | 69 | .clean-post: .clean-impl 70 | # Add your post 'clean' code here... 71 | 72 | 73 | # clobber 74 | clobber: .clobber-post 75 | 76 | .clobber-pre: 77 | # Add your pre 'clobber' code here... 78 | 79 | .clobber-post: .clobber-impl 80 | # Add your post 'clobber' code here... 81 | 82 | 83 | # all 84 | all: .all-post 85 | 86 | .all-pre: 87 | # Add your pre 'all' code here... 88 | 89 | .all-post: .all-impl 90 | # Add your post 'all' code here... 91 | 92 | 93 | # build tests 94 | build-tests: .build-tests-post 95 | 96 | .build-tests-pre: 97 | # Add your pre 'build-tests' code here... 98 | 99 | .build-tests-post: .build-tests-impl 100 | # Add your post 'build-tests' code here... 101 | 102 | 103 | # run tests 104 | test: .test-post 105 | 106 | .test-pre: build-tests 107 | # Add your pre 'test' code here... 108 | 109 | .test-post: .test-impl 110 | # Add your post 'test' code here... 111 | 112 | 113 | # help 114 | help: .help-post 115 | 116 | .help-pre: 117 | # Add your pre 'help' code here... 118 | 119 | .help-post: .help-impl 120 | # Add your post 'help' code here... 121 | 122 | 123 | 124 | # include project implementation makefile 125 | include nbproject/Makefile-impl.mk 126 | 127 | # include project make variables 128 | include nbproject/Makefile-variables.mk 129 | -------------------------------------------------------------------------------- /java/client/src/main/java/org/apidesign/demo/sieve/DataModel.java: -------------------------------------------------------------------------------- 1 | package org.apidesign.demo.sieve; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Timer; 6 | import java.util.TimerTask; 7 | import net.java.html.charts.Chart; 8 | import net.java.html.charts.Color; 9 | import net.java.html.charts.Config; 10 | import net.java.html.charts.Values; 11 | import net.java.html.json.Function; 12 | import net.java.html.json.Model; 13 | import net.java.html.json.ModelOperation; 14 | import net.java.html.json.Property; 15 | import org.apidesign.demo.sieve.eratosthenes.Primes; 16 | 17 | @Model(className = "Data", targetId="", instance = true, properties = { 18 | @Property(name = "message", type = String.class), 19 | @Property(name = "startOrStop", type = String.class), 20 | @Property(name = "running", type = boolean.class) 21 | }) 22 | final class DataModel { 23 | private static Data ui; 24 | 25 | private final Timer timer = new Timer("Compute primes"); 26 | private List data; 27 | 28 | @ModelOperation 29 | void initialize(Data model) { 30 | Chart chart = Chart.createLine(new Values.Set("a label", Color.valueOf("white"), Color.valueOf("black"))); 31 | data = chart.getData(); 32 | data.add(new Values("0", 0)); 33 | chart.applyTo("chart"); 34 | model.setStartOrStop("Start"); 35 | model.applyBindings(); 36 | } 37 | 38 | @Function 39 | void startStop(final Data model) { 40 | if (model.isRunning()) { 41 | model.setStartOrStop("Start"); 42 | model.setRunning(false); 43 | } else { 44 | model.setStartOrStop("Stop"); 45 | model.runMeasurement(Integer.MAX_VALUE); 46 | } 47 | } 48 | 49 | @ModelOperation 50 | void runMeasurement(final Data model, int cnt) { 51 | model.setRunning(true); 52 | final List results = new ArrayList<>(); 53 | final int[] count = { cnt }; 54 | class Schedule extends TimerTask { 55 | @Override 56 | public void run() { 57 | Primes p = new Primes() { 58 | @Override 59 | protected void log(String msg) { 60 | } 61 | }; 62 | long start = System.currentTimeMillis(); 63 | int value = p.compute(); 64 | int took = (int) (System.currentTimeMillis() - start); 65 | model.setMessage("Computing hundred thousand primes took " + took + " ms, last prime is " + value); 66 | results.add(took); 67 | if (model.isRunning() && count[0]-- > 0) { 68 | timer.schedule(new Schedule(), 1000); 69 | } else { 70 | model.addMeasurements(results); 71 | } 72 | checkShutdown(); 73 | } 74 | 75 | private boolean checkShutdown() { 76 | if (count[0] == 0) { 77 | model.setMessage("Shutting down..."); 78 | timer.schedule(new TimerTask() { 79 | @Override 80 | public void run() { 81 | if (model.isRunning()) { 82 | System.exit(0); 83 | } 84 | } 85 | }, 10000); 86 | return true; 87 | } 88 | return false; 89 | } 90 | } 91 | timer.schedule(new Schedule(), 1); 92 | } 93 | 94 | @ModelOperation 95 | void addMeasurements(Data model, List times) { 96 | for (Integer time : times) { 97 | data.add(new Values("#" + data.size(), time)); 98 | } 99 | } 100 | 101 | /** 102 | * Called when the page is ready. 103 | */ 104 | static void onPageLoad(Integer repeat) throws Exception { 105 | ui = new Data(); 106 | ui.initialize(); 107 | if (repeat != null) { 108 | ui.runMeasurement(repeat); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /c/nbproject/configurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | filter.h 8 | natural.h 9 | primes.h 10 | 11 | 14 | 15 | 18 | filter.c 19 | main.c 20 | natural.c 21 | primes.c 22 | 23 | 27 | 28 | 32 | Makefile 33 | 34 | 35 | Makefile 36 | 37 | 38 | 39 | default 40 | true 41 | false 42 | 43 | 44 | 45 | 3 46 | 47 | 48 | sieve 49 | 50 | Mathematics 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | default 72 | true 73 | false 74 | 75 | 76 | 77 | 5 78 | 3 79 | 80 | 81 | 5 82 | 83 | 84 | 5 85 | 86 | 87 | 5 88 | 89 | 90 | sieve 91 | 92 | Mathematics 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /c/nbproject/Makefile-impl.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Generated Makefile - do not edit! 3 | # 4 | # Edit the Makefile in the project folder instead (../Makefile). Each target 5 | # has a pre- and a post- target defined where you can add customization code. 6 | # 7 | # This makefile implements macros and targets common to all configurations. 8 | # 9 | # NOCDDL 10 | 11 | 12 | # Building and Cleaning subprojects are done by default, but can be controlled with the SUB 13 | # macro. If SUB=no, subprojects will not be built or cleaned. The following macro 14 | # statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf 15 | # and .clean-reqprojects-conf unless SUB has the value 'no' 16 | SUB_no=NO 17 | SUBPROJECTS=${SUB_${SUB}} 18 | BUILD_SUBPROJECTS_=.build-subprojects 19 | BUILD_SUBPROJECTS_NO= 20 | BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}} 21 | CLEAN_SUBPROJECTS_=.clean-subprojects 22 | CLEAN_SUBPROJECTS_NO= 23 | CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}} 24 | 25 | 26 | # Project Name 27 | PROJECTNAME=c 28 | 29 | # Active Configuration 30 | DEFAULTCONF=Debug 31 | CONF=${DEFAULTCONF} 32 | 33 | # All Configurations 34 | ALLCONFS=Debug Release 35 | 36 | 37 | # build 38 | .build-impl: .build-pre .validate-impl .depcheck-impl 39 | @#echo "=> Running $@... Configuration=$(CONF)" 40 | "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf 41 | 42 | 43 | # clean 44 | .clean-impl: .clean-pre .validate-impl .depcheck-impl 45 | @#echo "=> Running $@... Configuration=$(CONF)" 46 | "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf 47 | 48 | 49 | # clobber 50 | .clobber-impl: .clobber-pre .depcheck-impl 51 | @#echo "=> Running $@..." 52 | for CONF in ${ALLCONFS}; \ 53 | do \ 54 | "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf; \ 55 | done 56 | 57 | # all 58 | .all-impl: .all-pre .depcheck-impl 59 | @#echo "=> Running $@..." 60 | for CONF in ${ALLCONFS}; \ 61 | do \ 62 | "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf; \ 63 | done 64 | 65 | # build tests 66 | .build-tests-impl: .build-impl .build-tests-pre 67 | @#echo "=> Running $@... Configuration=$(CONF)" 68 | "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-tests-conf 69 | 70 | # run tests 71 | .test-impl: .build-tests-impl .test-pre 72 | @#echo "=> Running $@... Configuration=$(CONF)" 73 | "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .test-conf 74 | 75 | # dependency checking support 76 | .depcheck-impl: 77 | @echo "# This code depends on make tool being used" >.dep.inc 78 | @if [ -n "${MAKE_VERSION}" ]; then \ 79 | echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES} \$${TESTOBJECTFILES}))" >>.dep.inc; \ 80 | echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \ 81 | echo "include \$${DEPFILES}" >>.dep.inc; \ 82 | echo "endif" >>.dep.inc; \ 83 | else \ 84 | echo ".KEEP_STATE:" >>.dep.inc; \ 85 | echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \ 86 | fi 87 | 88 | # configuration validation 89 | .validate-impl: 90 | @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \ 91 | then \ 92 | echo ""; \ 93 | echo "Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}"; \ 94 | echo "See 'make help' for details."; \ 95 | echo "Current directory: " `pwd`; \ 96 | echo ""; \ 97 | fi 98 | @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \ 99 | then \ 100 | exit 1; \ 101 | fi 102 | 103 | 104 | # help 105 | .help-impl: .help-pre 106 | @echo "This makefile supports the following configurations:" 107 | @echo " ${ALLCONFS}" 108 | @echo "" 109 | @echo "and the following targets:" 110 | @echo " build (default target)" 111 | @echo " clean" 112 | @echo " clobber" 113 | @echo " all" 114 | @echo " help" 115 | @echo "" 116 | @echo "Makefile Usage:" 117 | @echo " make [CONF=] [SUB=no] build" 118 | @echo " make [CONF=] [SUB=no] clean" 119 | @echo " make [SUB=no] clobber" 120 | @echo " make [SUB=no] all" 121 | @echo " make help" 122 | @echo "" 123 | @echo "Target 'build' will build a specific configuration and, unless 'SUB=no'," 124 | @echo " also build subprojects." 125 | @echo "Target 'clean' will clean a specific configuration and, unless 'SUB=no'," 126 | @echo " also clean subprojects." 127 | @echo "Target 'clobber' will remove all built files from all configurations and," 128 | @echo " unless 'SUB=no', also from subprojects." 129 | @echo "Target 'all' will will build all configurations and, unless 'SUB=no'," 130 | @echo " also build subprojects." 131 | @echo "Target 'help' prints this message." 132 | @echo "" 133 | 134 | -------------------------------------------------------------------------------- /java/algorithm/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | org.apidesign.demo 6 | sieve-pom 7 | 1.0-SNAPSHOT 8 | 9 | 10 | org.apidesign.demo 11 | sieve-algorithm 12 | 1.0-SNAPSHOT 13 | bundle 14 | 15 | Sieve Implementation 16 | 17 | 18 | none 19 | 65535 20 | org.apidesign.demo.sieve.eratosthenes.Primes 21 | 22 | 23 | 24 | 25 | org.apache.felix 26 | maven-bundle-plugin 27 | 2.4.0 28 | true 29 | 30 | 31 | org.apidesign.demo.sieve.eratosthenes 32 | org.apidesign.demo.sieve.algorithm 33 | 34 | 35 | 36 | 37 | org.apache.maven.plugins 38 | maven-compiler-plugin 39 | 2.3.2 40 | 41 | 1.7 42 | 1.7 43 | 44 | 45 | 46 | org.apache.maven.plugins 47 | maven-jar-plugin 48 | 2.6 49 | 50 | 51 | 52 | ${mainClass} 53 | 54 | 55 | 56 | 57 | 58 | org.codehaus.mojo 59 | exec-maven-plugin 60 | 1.2.1 61 | 62 | ${mainClass} 63 | 64 | ${repeat} 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | org.testng 73 | testng 74 | test 75 | 76 | 77 | 78 | 79 | native-image 80 | 81 | 82 | native.image 83 | 84 | 85 | 86 | ${java.home}/bin/native-image 87 | 88 | 89 | 90 | 91 | org.codehaus.mojo 92 | exec-maven-plugin 93 | 1.6.0 94 | 95 | 96 | compile 97 | 98 | exec 99 | 100 | package 101 | 102 | ${native.image} 103 | 104 | -g 105 | -O0 106 | --static 107 | ${aot.profile} 108 | -H:Name=sieve 109 | -H:Path=${project.build.directory} 110 | -H:DashboardDump=${project.build.directory}/sieve 111 | -H:+DashboardAll 112 | -classpath 113 | 114 | ${mainClass} 115 | 116 | 117 | 118 | 119 | run 120 | 121 | exec 122 | 123 | 124 | ${project.build.directory}/sieve 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /java/client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | org.apidesign.demo 8 | sieve-pom 9 | 1.0-SNAPSHOT 10 | 11 | 12 | org.apidesign.demo 13 | sieve 14 | 1.0-SNAPSHOT 15 | bundle 16 | 17 | Sieve of E. Java General Code 18 | 19 | 20 | all 21 | org.apidesign.demo.sieve.Main 22 | ${java.home}/bin/java 23 | -Ddebug=false 24 | 0 25 | 26 | 27 | 28 | 29 | org.apache.felix 30 | maven-bundle-plugin 31 | 2.4.0 32 | true 33 | 34 | 35 | org.apidesign.demo.sieve 36 | org.apidesign.demo.sieve 37 | 38 | 39 | 40 | 41 | org.apache.maven.plugins 42 | maven-compiler-plugin 43 | 2.3.2 44 | 45 | 1.7 46 | 1.7 47 | 48 | 49 | 50 | org.apache.maven.plugins 51 | maven-jar-plugin 52 | 2.4 53 | 54 | 55 | 56 | ${project.mainclass} 57 | true 58 | lib/ 59 | false 60 | 61 | 62 | 63 | 64 | 65 | maven-source-plugin 66 | 2.2.1 67 | 68 | 69 | attach-sources 70 | post-integration-test 71 | 72 | jar-no-fork 73 | 74 | 75 | 76 | 77 | 78 | org.codehaus.mojo 79 | exec-maven-plugin 80 | 1.2.1 81 | 82 | ${exec.java.bin} 83 | test 84 | 85 | -classpath 86 | 87 | -Dbrowser.rootdir=${basedir}/src/main/webapp/ 88 | -Dnetbeans.inspect.port=${netbeans.inspect.port} 89 | ${exec.debug.arg} 90 | ${project.mainclass} 91 | ${repeat} 92 | 93 | 94 | 95 | 96 | maven-assembly-plugin 97 | 2.4 98 | 99 | 100 | web-pages 101 | package 102 | 103 | single 104 | 105 | 106 | 107 | src/main/assembly/webpages.xml 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | org.netbeans.html 118 | net.java.html 119 | ${net.java.html.version} 120 | 121 | 122 | org.netbeans.html 123 | net.java.html.json 124 | ${net.java.html.version} 125 | 126 | 127 | org.netbeans.html 128 | net.java.html.boot 129 | ${net.java.html.version} 130 | 131 | 132 | org.netbeans.html 133 | net.java.html.sound 134 | ${net.java.html.version} 135 | 136 | 137 | org.netbeans.html 138 | ko4j 139 | ${net.java.html.version} 140 | runtime 141 | 142 | 143 | org.testng 144 | testng 145 | test 146 | 147 | 148 | org.netbeans.html 149 | net.java.html.boot.script 150 | ${net.java.html.version} 151 | test 152 | jar 153 | 154 | 155 | org.apidesign.demo 156 | sieve-algorithm 157 | ${project.version} 158 | 159 | 160 | org.netbeans.html 161 | net.java.html.boot.fx 162 | ${net.java.html.version} 163 | provided 164 | 165 | 166 | com.dukescript.api 167 | charts 168 | ${charts.version} 169 | 170 | 171 | org.netbeans.html 172 | net.java.html.boot 173 | 174 | 175 | 176 | 177 | 178 | 179 | jdk11 180 | 181 | 11 182 | 183 | 184 | 185 | org.openjfx 186 | javafx-web 187 | 11 188 | runtime 189 | 190 | 191 | 192 | 193 | desktop 194 | 195 | 196 | org.netbeans.html 197 | net.java.html.boot.fx 198 | ${net.java.html.version} 199 | runtime 200 | 201 | 202 | 203 | 204 | 205 | maven-assembly-plugin 206 | 2.4 207 | 208 | 209 | distro-assembly 210 | package 211 | 212 | single 213 | 214 | 215 | 216 | src/main/assembly/javafx.xml 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sieves of Eratosthenes in Many Languages 2 | 3 | Implementing the sieve of Eratosthenes in various languages to demonstrate 4 | power of GraalVM and Truffle. Please download 5 | [GraalVM](http://www.oracle.com/technetwork/oracle-labs/program-languages/overview/index.html) 6 | before proceeding with experiments. The [code in this repository](https://github.com/jtulach/sieve/) 7 | has been tested to work with [GraalVM](http://graalvm.org) 8 | version `19.3.1`. 9 | 10 | [![Build Status](https://travis-ci.org/jtulach/sieve.svg?branch=master)](https://travis-ci.org/jtulach/sieve) 11 | 12 | ## Ruby Speed 13 | 14 | Use following commands to find out that GraalVM Ruby is ten times faster than any other one. 15 | The program computes first one hundred thousands of prime numbers using the 16 | [Sieve of Eratosthenes](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes) algorithm. 17 | It repeats the computation in an endless loop to simulate long running process 18 | and give **GraalVM Ruby** time to warm up and optimize. 19 | 20 | ```bash 21 | $ ruby ruby/sieve.rb 22 | $ graalvm/bin/ruby ruby/sieve.rb 23 | ``` 24 | 25 | MRI Ruby starts fast and then gets slow. GraalVM has long initialization period, 26 | but once it is running, it is faster. After few iterations it gets about 10x faster 27 | than regular Ruby installed on my Ubuntu. Regular Ruby needs more than 2s to 28 | compute the primes. **GraalVM Ruby** at the end needs less than 150ms on my laptop. 29 | 30 | ## JavaScript 31 | 32 | Of course, these days the most optimized dynamic language runtimes are for JavaScript, so shouldn't we rewrite our code to be faster? Yes, we can try that: 33 | 34 | ```bash 35 | $ node js/sieve.js 36 | $ graalvm/bin/node js/sieve.js 37 | ``` 38 | 39 | We can see that after few warm-up iterations both systems achieve similar 40 | peek performance. On my computer one iteration takes around 130ms. 41 | That is still faster than GraalVM Ruby, but only a bit (compared to 42 | more than 20x to MRI - the standard Ruby implementation). Whether that justifies 43 | rewriting whole application from one language to another depends on the actual 44 | need for speed. Moreover there are better options... 45 | 46 | ## Spice Ruby with JavaScript 47 | 48 | Rather than rewriting whole application into a new language, why not rewrite 49 | just the critical parts? Let's keep the computation of natural numbers in Ruby 50 | and do the sieve operations in JavaScript: 51 | 52 | ```bash 53 | $ graalvm/bin/polyglot --file ruby+js/sieve.rb --file ruby+js/sieve.js 54 | ``` 55 | 56 | A combination of languages is hard to compare, as there is no other system that 57 | could combine 100% language complete Ruby with 100% language complete JavaScript. 58 | There are some transpilers of Ruby to JavaScript, but they are far from complete 59 | and clearly they are obsolete - **GraalVM** can run the mixture of **Ruby** and **JavaScript** 60 | as fast as optimized JavaScript only version. 61 | 62 | ## Can I add Java? 63 | 64 | Those coming from a JavaScript or Ruby camp, interested only in the scripting 65 | languages may stop reading now. The rest of us, who write or maintain application 66 | in Java maybe asking: Should I rewrite my Java app to get this kind of interop? 67 | 68 | No, there is no need! GraalVM is full featured Java VM compatible with the 69 | most recent release of Java (you need [Maven](http://maven.apache.org) to proceed), 70 | just try: 71 | 72 | ```bash 73 | JAVA_HOME=graalvm mvn -q clean package exec:exec -f ruby+js/fromjava/pom.xml 74 | ``` 75 | 76 | Again, after few iterations the peak performance of the code is reached, but 77 | this time it is embedded into a Java program. You can get all the speed of 78 | Truffle from your Java applications, if you execute on top of GraalVM! 79 | 80 | ## Can I use Java Scripting API? 81 | 82 | Of course, it is fair to ask whether, in order to use 83 | [GraalVM](http://www.oracle.com/technetwork/oracle-labs/program-languages/overview/index.html) 84 | one has to learn the special [Polyglot API](http://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/package-summary.html)? 85 | 86 | If you are only interested in interop between Java and JavaScript, then you 87 | don't have to! You can use the standard `ScriptEngineManager` search for 88 | an engine named `Graal.js` and use it as you are used to. Here is an example: 89 | ```bash 90 | mvn -f js/fromjava/pom.xml package exec:exec 91 | ``` 92 | The command can use regular HotSpot virtual machine and executes the `sieve.js` 93 | script via its integrated `JavaScript` engine. Btw. the JDK's Nashorn can 94 | compute the hundred thousand of prime numbers in 240ms on my computer. 95 | 96 | Now run the same script with GraalVM: 97 | ```bash 98 | JAVA_HOME=graalvm mvn -f js/fromjava/pom.xml package exec:exec 99 | ``` 100 | The same Java code, the same JavaScript file - and the performance? Less than 101 | 90ms on my computer! 102 | 103 | ## Is R slower than Ruby? 104 | 105 | Now imagine you have even slower language than Ruby. Is it possible? Yes, 106 | it is. Language like [R](https://en.wikipedia.org/wiki/R_%28programming_language%29) is even slower and yet very popular 107 | (among statisticians). Nice thing is that it works primarily on vectors, so 108 | we can generate the list of natural numbers as a simple ***[2:999999999]*** 109 | expression. Can Graal make that fast? 110 | 111 | ```bash 112 | $ graalvm/bin/polyglot --jvm --file R+js/sieve.R --file R+js/sieve.js 113 | ``` 114 | 115 | JavaScript is accessing enormously huge vector from R (which is never really 116 | created) and the speed is? Great! Within 10-20% of the fastest solution we have seen so far. 117 | 118 | ## Aren't These Scripting Languages Slower than Java? 119 | 120 | We have seen that with **Truffle** almost any language is almost as fast as the fastest 121 | implementation of *JavaScript*. But what about *Java*? Isn't it supposed to be 122 | faster? Yes, it is. Try: 123 | 124 | ```bash 125 | $ mvn -f java/pom.xml install 126 | $ mvn -f java/algorithm/pom.xml exec:java 127 | ``` 128 | 129 | and you can see that *Java* is really fast. On my computer it takes something 130 | like 100ms to finish one iteration. However we can be even faster! How? 131 | Let's just switch to the **GraalVM** and use it instead of the regular one: 132 | 133 | ```bash 134 | $ mvn -f java/pom.xml install 135 | $ JAVA_HOME=graalvm mvn -f java/algorithm/pom.xml exec:java 136 | ``` 137 | 138 | One iteration of the sieve of Eratosthenes algorithm now runs in less than 139 | 90ms on my computer. **GraalVM** rules! 140 | 141 | ## But Java cannot Run in a Browser! 142 | 143 | That is not entirely true. The Apache 144 | [HTML+Java API](http://bits.netbeans.org/html+java/) and 145 | related projects gives us an easy way to run Java in a browser. Try it: 146 | 147 | ```bash 148 | $ mvn -f java/pom.xml install 149 | $ mvn -f java/client/pom.xml exec:exec -Drepeat=5 150 | ``` 151 | 152 | The same algorithm written in Java is executed and the result is displayed in an opened browser window. 153 | Well, it is not really a browser, it is just an WebView component. But even that can be fixed! Try: 154 | 155 | ```bash 156 | $ mvn -f java/pom.xml install 157 | $ mvn -f java/client-web/pom.xml bck2brwsr:show 158 | ``` 159 | 160 | and now your *Java*(!) code runs in real browser. 161 | Visit [DukeScript](https://dukescript.com/) project to learn more 162 | about using Java in a browser. 163 | 164 | And the speed? Amazing, code written in *Java* and transpilled to 165 | *JavaScript* runs at most 50% slower than Java on classical JVM. 166 | 167 | ## Nothing Compares to C! 168 | 169 | A friend of mine once asked: *"Nice, but if I write the code in C, then ..., right?"* 170 | That forced me to sit down and write a 171 | [C version of the sieve](c/main.c). 172 | Indeed it is fast, but it is not really polyglot. Can we fix that? 173 | 174 | GraalVM offers a way to *interpret* the **C** code with a 175 | Truffle interpreter. Interpret **C**? 176 | Isn't that going to be slow? No, not really, 177 | if you use [Sulong](https://github.com/graalvm/sulong/) - an 178 | [LLVM](http://llvm.org/) interpreter that is part of GraalVM. 179 | 180 | 181 | Let's try to compare statically compiled C and Sulong speed: 182 | ```bash 183 | $ make -C c 184 | $ ./c/sieve 185 | Hundred thousand prime numbers in 103 ms 186 | ``` 187 | it starts fast and runs fast. Now it's the Sulong's turn! We need an LLVM bitcode. 188 | Get it from `clang` and then pass it to `lli` of GraalVM: 189 | ```bash 190 | $ cd c 191 | sieve/c$ clang -c -emit-llvm *.c 192 | sieve/c$ graalvm/bin/lli --lib natural.bc --lib filter.bc --lib primes.bc main.bc 193 | Hundred thousand prime numbers in 114 ms 194 | ``` 195 | The interpreted code isn't as fast as the native one, but it is not slow either. 196 | Moreover there is a huge benefit - it can be easily mixed with other languages 197 | without any slowdown common when crossing the language boundaries. 198 | 199 | ## Go with a Single File! 200 | 201 | The are some good properties of the C solution. No need for virtual machine 202 | overhead being one of them. Ability to generate single `sieve` file that 203 | carries all the implementation being another. On the other hand, C isn't 204 | really type safe language and also doesn't offer any automatic memory 205 | management. Maybe we should try the Go language!? Or: 206 | 207 | Can we generate a single, virtual machine less, self-contained file 208 | with GraalVM? Yes, we can. There is a `native-image` command that 209 | allows us to compile the `java/algorithm` project into a self contained binary: 210 | ```bash 211 | $ JAVA_HOME=graalvm mvn -f java/algorithm -Pnative-image install 212 | /sieve/java/algorithm/target/sieve:8297] [total]: 36,794.95 ms 213 | $ ls -lh java/algorithm/target/sieve 214 | 6,5M java/algorithm/target/sieve 215 | $ java/algorithm/target/sieve 216 | Hundred thousand primes computed in 95 ms 217 | ``` 218 | Not only one gets a self contained `sieve` executable of a reasonable (e.g. 7M) 219 | size, but it is also fast and most of all, it doesn't need any warm up. It 220 | is consistently fast since begining! 221 | 222 | ## Going Docker! 223 | 224 | With a single self contained file created by `native-image` in previous 225 | section, it is easy to join the cloud life style. A simple docker file 226 | ```docker 227 | FROM alpine:3.6 228 | COPY ./target/sieve /bin/sieve 229 | CMD /bin/sieve 230 | ``` 231 | will create small (10MB) docker image with your sieve application. 232 | The following commands do it on an Ubuntu Linux AMD64 box: 233 | ```bash 234 | $ JAVA_HOME=graalvm mvn -f java/algorithm -Pnative-image install 235 | $ docker build java/algorithm/ 236 | Step 1/3 : FROM alpine:3.6 237 | Step 2/3 : COPY ./target/sieve /bin/sieve 238 | Step 3/3 : CMD /bin/sieve 239 | Successfully built a06b45ee7d68 240 | $ docker run a06b45ee7d68 241 | $ docker ps 242 | $ docker kill d6ca88781a31 243 | ``` 244 | Your effective Java application has just gone to the cloud! 245 | 246 | # Real Polyglot 247 | 248 | Learn to use [GraalVM](http://www.oracle.com/technetwork/oracle-labs/program-languages/overview/index.html) 249 | as then you become real polyglot: You'll be able to code in any dynamic language, 250 | mix them together and even use Java whenever you want. 251 | -------------------------------------------------------------------------------- /java/client-web/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | org.apidesign.demo 8 | sieve-pom 9 | 1.0-SNAPSHOT 10 | 11 | 12 | org.apidesign.demo 13 | sieve-web 14 | 1.0-SNAPSHOT 15 | jar 16 | 17 | Sieve of Eratosthenes for Web 18 | 19 | 20 | none 21 | org.apidesign.demo.sieve.BrowserMain 22 | initialize bck2brwsr --> 23 | <script type="text/javascript" src="bck2brwsr.js"></script> 24 | <script> 25 | var vm = bck2brwsr('sieve.js'); 26 | var c = vm.loadClass('org.apidesign.demo.sieve.BrowserMain'); 27 | c.invoke('main'); 28 | </script> 29 | <!-- end of initialization 30 | 31 | 32 | 33 | 34 | org.netbeans.html 35 | html4j-maven-plugin 36 | ${net.java.html.version} 37 | 38 | 39 | js-classes 40 | 41 | process-js-annotations 42 | 43 | 44 | 45 | 46 | 47 | org.apache.maven.plugins 48 | maven-compiler-plugin 49 | 2.3.2 50 | 51 | 1.7 52 | 1.7 53 | 54 | netbeans.ignore.jdk.bootclasspath 55 | 56 | 57 | 58 | 59 | org.apache.maven.plugins 60 | maven-jar-plugin 61 | 2.4 62 | 63 | 64 | 65 | ${project.mainclass} 66 | true 67 | lib/ 68 | false 69 | 70 | 71 | 72 | 73 | 74 | org.apidesign.bck2brwsr 75 | bck2brwsr-maven-plugin 76 | ${bck2brwsr.version} 77 | 78 | 79 | 80 | brwsr 81 | aot 82 | 83 | 84 | 85 | 86 | ${bck2brwsr.obfuscationlevel} 87 | ${project.build.directory}/${project.build.finalName}-bck2brwsr/public_html/ 88 | index.html 89 | lib 90 | ${project.build.directory}/sieve.js 91 | 92 | ${project.mainclass} 93 | 94 | 95 | 96 | 97 | maven-assembly-plugin 98 | 2.4 99 | 100 | 101 | distro-assembly 102 | package 103 | 104 | single 105 | 106 | 107 | 108 | src/main/assembly/bck2brwsr.xml 109 | 110 | 111 | 112 | 113 | 114 | 115 | org.apache.maven.plugins 116 | maven-dependency-plugin 117 | 2.9 118 | 119 | 120 | unpack 121 | process-resources 122 | 123 | unpack-dependencies 124 | 125 | 126 | 127 | 128 | zip 129 | webpages 130 | true 131 | target/web/pages 132 | */** 133 | ${project.groupId} 134 | 135 | 136 | 137 | org.apache.maven.plugins 138 | maven-surefire-plugin 139 | 2.19.1 140 | 141 | com.dukescript.api:junit-osgi 142 | 143 | false 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | org.apidesign.demo 152 | sieve 153 | ${project.version} 154 | 155 | 156 | org.netbeans.html 157 | net.java.html.boot.fx 158 | 159 | 160 | org.jetbrains.kotlin 161 | kotlin-stdlib-common 162 | 163 | 164 | org.jetbrains 165 | annotations 166 | 167 | 168 | org.openjfx 169 | javafx-web 170 | 171 | 172 | 173 | 174 | org.apidesign.bck2brwsr 175 | emul 176 | ${bck2brwsr.version} 177 | rt 178 | 179 | 180 | org.netbeans.html 181 | net.java.html.boot 182 | ${net.java.html.version} 183 | 184 | 185 | asm 186 | org.ow2.asm 187 | 188 | 189 | 190 | 191 | org.apidesign.bck2brwsr 192 | emul 193 | ${bck2brwsr.version} 194 | bck2brwsr 195 | provided 196 | 197 | 198 | org.apidesign.bck2brwsr 199 | ko-bck2brwsr 200 | ${bck2brwsr.version} 201 | bck2brwsr 202 | provided 203 | 204 | 205 | 206 | 207 | 208 | com.dukescript.api 209 | junit-osgi 210 | test 211 | 212 | 213 | com.dukescript.api 214 | junit-browser-runner 215 | ${junit.browser.version} 216 | test 217 | jar 218 | 219 | 220 | 221 | 222 | org.netbeans.html 223 | net.java.html.boot.fx 224 | ${net.java.html.version} 225 | test 226 | 227 | 228 | com.oracle 229 | javafx 230 | 231 | 232 | 233 | 234 | 235 | 236 | org.apidesign.bck2brwsr 237 | launcher.http 238 | ${bck2brwsr.version} 239 | test 240 | jar 241 | 242 | 243 | com.dukescript.api 244 | junit-browser-runner 245 | ${junit.browser.version} 246 | test 247 | bck2brwsr 248 | jar 249 | 250 | 251 | 252 | 253 | teavm 254 | 255 | 0.5.1 256 | false 257 | initialize TeaVM --> 258 | <script type="text/javascript" src="teavm.js"></script> 259 | <script> 260 | main(); 261 | </script> 262 | <!-- end of initialization 263 | 264 | 265 | 266 | 267 | org.netbeans.html 268 | ko4j 269 | ${net.java.html.version} 270 | 271 | 272 | 273 | 274 | 275 | org.teavm 276 | teavm-maven-plugin 277 | ${teavm.version} 278 | 279 | 280 | org.teavm 281 | teavm-classlib 282 | ${teavm.version} 283 | 284 | 286 | 287 | org.teavm 288 | teavm-html4j 289 | ${teavm.version} 290 | 291 | 292 | 293 | 294 | generate-teavm 295 | 296 | compile 297 | 298 | process-classes 299 | 300 | ${project.mainclass} 301 | ${teavm.debug} 302 | ${teavm.debug} 303 | ${teavm.debug} 304 | 305 | false 306 | 307 | false 308 | 309 | MERGED 310 | 311 | teavm.js 312 | ${project.build.directory}/teavm 313 | 319 | 320 | 321 | 322 | 323 | 324 | maven-assembly-plugin 325 | 2.4 326 | 327 | 328 | distro-assembly 329 | package 330 | 331 | single 332 | 333 | 334 | 335 | src/main/assembly/teavm.xml 336 | 337 | 338 | 339 | 340 | 341 | 342 | org.apidesign.bck2brwsr 343 | bck2brwsr-maven-plugin 344 | ${bck2brwsr.version} 345 | 346 | 347 | 348 | brwsr 349 | 350 | 351 | 352 | 353 | ${project.build.directory}/${project.build.finalName}-teavm/public_html/ 354 | index.html 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | --------------------------------------------------------------------------------