?

Log in

No account? Create an account

Previous Entry | Next Entry

Go vs Swift vs C++ microbenchmark

Looking at the Swift vs Go vs Python battle, couldn't help but notice its old age. It was written almost 12 months ago and the weight of time clearly shows. In a fast paced race towards ecosystem simplicity that we observe nowadays, a year is a lot.

So on my Macbook Air (1.7 GHz Intel Core i5) I decided to repeat the test, and add C++ to the mix. It is too easy to test against python (which is about 10x slower than the "compiled" languages), so C++ should be a fair competition. Go 1.5.3, Swift 2.1.1, C++ clang-700.1.81.

I don't propose taking my test seriously. The micro-benchmarking doesn't tell us much about about the language ecosystem, tooling, maintainability, surface area of a language, etc, etc. It even doesn't tell us too much about performance. But you know the drill. If you see a micro-benchmark, puke and close the window. Don't read any further.

Nevertheless! There's some source.

GoSwiftC++
package main
import "fmt"

func main() {
    var sum int64 = 0

    for e := 0; e < 200; e++ {
        sum = 0

        var x[]int64
        for i := 0 ; i < 1000000; i++ {
            x = append(x, int64(i));
        }

        var y[]int64
        for i := 0 ; i < 1000000-1; i++ {
            y = append(y, x[i]+x[i+1]);
        }

        for i := 0 ; i < 1000000; i += 100 {
            sum += y[i];
        }
    
    }
    
    fmt.Println(sum);
}
var sum : Int64 = 0

for e in 0..<200 {
    sum = 0 
    
    var x : [Int64] = []
    for (var i = 0; i < 1000000; i++) {
        x.append(Int64(i));
    }
        
    var y: [Int64] = []
    for (var i = 0; i < 1000000-1; i++) {
        y.append(x[i] + x[i+1]);
    }
        
    for (var i = 0; i < 1000000; i+=100) {
        sum += y[i]
    }   
}
        
print(sum)  
#include <vector>
#include <iostream>

int main() {
    int64_t sum = 0;

    for(int e = 0; e < 200; e++) {
        sum = 0;

        std::vector<int64_t> x;
        for(int i = 0; i < 1000000; i++) {
            x.push_back(i);
        }

        std::vector<int64_t> y;
        for(int i = 0; i < 1000000-1; i++) {
            y.push_back(x[i] + x[i+1]);
        }

        for (int i = 0; i < 1000000; i += 100) {
            sum += y[i];
        }
    }

    std::cout << sum << std::endl;
}


Why I chose int64 instead of int? On my 64-bit platform the C++'s int is 32 bit, whereas Go's and Swift's default ints are 64-bit. I wanted to level the playing field a little.

Anyway. Let's the battle begin:

go build -o test-go go/test.go
swiftc -O -o test-swift swift/test.swift
c++ -O3 -o test-c cplusplus/test.cc
GOMAXPROCS=2 time ./test-go
9999010000
        4.32 real         5.99 user         0.38 sys
GOMAXPROCS=1 time ./test-go
9999010000
        3.93 real         3.89 user         0.05 sys
time ./test-swift
9999010000
        3.96 real         2.82 user         1.12 sys
time ./test-c
9999010000
        2.37 real         1.74 user         0.62 sys


What we see here? With Go, GOMAXPROCS adds measurable overhead. As expected. But not that huge. C++ is predictably faster. No surprise here. In fact, this appears to be mostly a competition of memory allocators and GCs (where applicable), and Swift and Go are rather on par with each other.

But let's try a smaller array so memory allocation becomes a bit less of an issue. The following test was made with e<=2000 (instead of 200) and loop iterations to 100k instead of 1m:

go build -o test-go go/test.go
swiftc -O -o test-swift swift/test.swift
c++ -O3 -o test-c cplusplus/test.cc
GOMAXPROCS=2 time ./test-go
99901000
        4.40 real         5.65 user         1.10 sys
GOMAXPROCS=1 time ./test-go
99901000
        5.06 real         5.07 user         0.83 sys
time ./test-swift
99901000
        2.32 real         2.29 user         0.01 sys
time ./test-c
99901000
        1.39 real         1.37 user         0.01 sys


Now, we're talking. Go is lagging behind, perhaps because of its reliance on its own code generator. This gets us into "3x slower than C" domain. Swift is using LLVM, the same code generator my C++'s compiler uses under the hood. But it adds some checks and GC, so Swift also exhibits a serious slowdown, though well within 2x of C++.

What we can take from it?

I suspect that if Swift had first class concurrency support while managing to retain its speed, many people would consider it instead of Go. But we can't have both. Either we have a speedy and high maintenance language, or concurrent but a bit slow language, and then Swift.

...and we also have Erlang, but its benchmark didn't fit on my charts :)

Comments

( 86 comments — Leave a comment )
thesz
Feb. 11th, 2016 12:47 pm (UTC)
You also conveniently omitted Haskell.
lionet
Feb. 11th, 2016 01:43 pm (UTC)
Yes, quite conveniently. It is rather hard to figure what algorithm would be considered "close enough" not to demonstrate any unfair advantage (such as not computing a big chunk of stuff).

Here's my attempt at fairness. I largely failed, but I couldn't slow it down any more:
go build -o test-go go/test.go
swiftc -O -o test-swift swift/test.swift
c++ -O3 -o test-c cplusplus/test.cc
ghc -O3 -o test-hask haskell/test.hs
Linking test-hask ...
GOMAXPROCS=2 time ./test-go
9999010000
        0.53 real         0.69 user         0.08 sys
GOMAXPROCS=1 time ./test-go
9999010000
        0.59 real         0.54 user         0.04 sys
time ./test-swift
9999010000
        5.57 real         4.05 user         1.48 sys
time ./test-c
9999010000
        0.32 real         0.22 user         0.09 sys
time ./test-hask
9999010000
        0.17 real         0.15 user         0.00 sys


Source:
{-# LANGUAGE ParallelListComp #-}
import Control.Monad

main = times 20 (compute 1000000) >>= print
    where
        times n m = do
            results <- replicateM n m
            return ((sum results) `seq` (head results))

compute n = do
    let xs = [0 .. (n-1)]
        ys = [x+k | x <- xs | k <- drop 1 xs]
    return $ sum $ map snd $ filter fst [((i`mod`100)==0,y) | y <- ys | i <- [0,1..]]


(To non-haskellers: this is NOT IDIOMATIC! This is fugly. This was specifically designed to look more imperative and close tho the Go/Swift/C++ code than it should have!)
(no subject) - thesz - Feb. 11th, 2016 01:52 pm (UTC) - Expand
(no subject) - dmzlj - Feb. 11th, 2016 02:22 pm (UTC) - Expand
(no subject) - dmzlj - Feb. 11th, 2016 02:16 pm (UTC) - Expand
rainman_rocks
Feb. 11th, 2016 12:54 pm (UTC)
I'd like to see Rust's numbers (although, the last time I tried some string processing, it was embarassingly slow - worse than PyPy).
lionet
Feb. 11th, 2016 01:47 pm (UTC)
You try :)
(no subject) - ryukzak - Feb. 11th, 2016 03:48 pm (UTC) - Expand
(no subject) - maxim - Dec. 30th, 2016 07:56 pm (UTC) - Expand
thedeemon
Feb. 11th, 2016 01:33 pm (UTC)
I don't see any optimization flags when invoking Go compiler. Ah, that's because there are no such flags and no optimization at all. This is why it compiles quickly, Go's dirty secret. ;)
lionet
Feb. 11th, 2016 01:45 pm (UTC)
Actually, the first numbers were taken with go run source.go. It was 30% slower than Swift. I tried to figure out why is it that slow. Turned out, I was timing it including the compile phase ;)

However, here are the compile times for all of the languages:

time go build -o test-go go/test.go
        0.55 real         0.57 user         0.12 sys
time swiftc -O -o test-swift swift/test.swift
        0.35 real         0.30 user         0.03 sys
time c++ -O3 -o test-c cplusplus/test.cc
        0.56 real         0.51 user         0.04 sys
time ghc -O3 -o test-hask haskell/test.hs
Linking test-hask ...
        0.46 real         0.34 user         0.10 sys


As you see, Swift is even faster.

Edited at 2016-02-11 01:46 pm (UTC)
(no subject) - dmzlj - Feb. 11th, 2016 02:30 pm (UTC) - Expand
(no subject) - thedeemon - Feb. 11th, 2016 02:47 pm (UTC) - Expand
dmzlj
Feb. 11th, 2016 01:53 pm (UTC)
I luv microbenchmarks:

dmz@safire:~/wtf/bench$ rm ./a.out 
dmz@safire:~/wtf/bench$ g++ -O2 ./cc.cc -o cc
dmz@safire:~/wtf/bench$ ./cc
9999010000
dmz@safire:~/wtf/bench$ time ./cc
9999010000

real	0m2.958s
user	0m1.092s
sys	0m1.864s
dmz@safire:~/wtf/bench$ time ./bench 
9999010000

real	0m0.141s
user	0m0.124s
sys	0m0.016s


bench.hs
module Main where

import Data.Vector (generate,(!),Vector(..))
import qualified Data.Vector as V
import qualified Data.List as L

import Control.Monad as C

main :: IO ()
main = do

  s <- forM [0..200] $ \_ -> do
         let x = generate 1000000 id
         let y = generate (1000000-1) (\i -> (x ! i)  + (x ! (i+1)) )
         return $ sum $ fmap (y !) [0,100 .. (1000000-1)]

  print (L.last s)




lionet
Feb. 11th, 2016 02:00 pm (UTC)
Try `seq`'ing the results though. You're not computing any results except the last one.
(no subject) - dmzlj - Feb. 11th, 2016 02:07 pm (UTC) - Expand
I luv microbenchmarks! - dmzlj - Feb. 11th, 2016 02:19 pm (UTC) - Expand
Re: I luv microbenchmarks! / - dmzlj - Feb. 11th, 2016 02:21 pm (UTC) - Expand
Re: I luv microbenchmarks! / - dmzlj - Feb. 11th, 2016 02:54 pm (UTC) - Expand
Re: I luv microbenchmarks! / - rblaze - Feb. 12th, 2016 07:20 am (UTC) - Expand
Re: I luv microbenchmarks! / - dmzlj - Feb. 12th, 2016 07:22 am (UTC) - Expand
Re: I luv microbenchmarks! / - rblaze - Feb. 12th, 2016 07:27 am (UTC) - Expand
Re: I luv microbenchmarks! / - lionet - Feb. 12th, 2016 07:27 am (UTC) - Expand
(no subject) - thedeemon - Feb. 11th, 2016 02:51 pm (UTC) - Expand
(no subject) - dmzlj - Feb. 11th, 2016 02:57 pm (UTC) - Expand
(no subject) - dmzlj - Feb. 11th, 2016 03:00 pm (UTC) - Expand
(no subject) - thedeemon - Feb. 11th, 2016 03:04 pm (UTC) - Expand
(no subject) - dmzlj - Feb. 11th, 2016 03:12 pm (UTC) - Expand
(no subject) - dmzlj - Feb. 11th, 2016 03:14 pm (UTC) - Expand
(no subject) - dmzlj - Feb. 11th, 2016 03:33 pm (UTC) - Expand
(no subject) - thedeemon - Feb. 11th, 2016 04:04 pm (UTC) - Expand
(no subject) - dmzlj - Feb. 11th, 2016 04:23 pm (UTC) - Expand
(no subject) - thedeemon - Feb. 11th, 2016 04:30 pm (UTC) - Expand
(no subject) - dmzlj - Feb. 11th, 2016 06:14 pm (UTC) - Expand
(no subject) - dmzlj - Feb. 12th, 2016 07:50 am (UTC) - Expand
(no subject) - thedeemon - Feb. 12th, 2016 08:55 am (UTC) - Expand
(no subject) - dmzlj - Feb. 12th, 2016 09:55 am (UTC) - Expand
(no subject) - thedeemon - Feb. 12th, 2016 10:39 am (UTC) - Expand
(no subject) - dmzlj - Feb. 12th, 2016 11:21 am (UTC) - Expand
(Deleted comment)
lionet
Feb. 11th, 2016 02:00 pm (UTC)
Not at 6 AM. However, you can give me a version to test.
(no subject) - ak47m - Feb. 12th, 2016 02:50 pm (UTC) - Expand
(no subject) - ak47m - Feb. 15th, 2016 05:46 am (UTC) - Expand
ewgrafus
Feb. 11th, 2016 03:57 pm (UTC)
You can play a little bit with Go garbage collector:
GOGC default - 100

export GOGC=100
ewgra@ewgra:~ $ time ./a
9999010000

real 0m4.581s
user 0m6.076s
sys 0m0.416s
ewgra@ewgra:~ $ export GOGC=10000
ewgra@ewgra:~ $ time ./a
9999010000

real 0m3.575s
user 0m3.544s
sys 0m0.240s

Kajal Sinha
Sep. 6th, 2016 08:42 am (UTC)
You did not use -O with rustc
you did not use -O with rustc. Rust is faster than swift if you see.

bash-3.2$ time ./swift-test
9999010000

real 0m2.859s
user 0m2.111s
sys 0m0.732s
bash-3.2$ time ./rust-test
9999010000

real 0m2.559s
user 0m1.307s
sys 0m1.239s
and_cesbo
Feb. 11th, 2016 04:26 pm (UTC)
Rust O_o:

$ time ./test-rust
9999010000

real 0m54.801s
user 0m51.158s
sys 0m2.547s

fn main() {
    let mut sum: i64 = 0;

    for _e in 0 .. 200 {
        sum = 0;

        let mut x: Vec<i64> = Vec::new();
        for i in 0 .. 1000000 {
            x.push(i);
        }

        let mut y: Vec<i64> = Vec::new();
        for i in 0 .. 1000000 - 1 {
            y.push(x[i] + x[i + 1]);
        }

        let mut i = 0;
        loop {
            sum += y[i];
            i += 100;
            if i >= 1000000 {
                break;
            }
        }
    }
    println!("{}", sum);
}


C++
$ time ./test-cc 
9999010000

real	0m2.978s
user	0m2.062s
sys	0m0.909s


Edited at 2016-02-11 04:27 pm (UTC)
4da
Feb. 11th, 2016 04:41 pm (UTC)
try this shit
fn main() {
let mut sum: i64 = 0;

for _ in 0..200 {
sum = 0;

let mut x = vec![];
for i in 0..1000000 {
x.push(i);
}

let mut y = vec![];
for i in 0..1000000-1 {
y.push(x[i] + x[i+1]);
}

let mut i = 0;
while i < 1000000 {
sum += y[i];
i += 100;
}
}
println!("{}", sum);
}
Re: try this shit - and_cesbo - Feb. 11th, 2016 04:57 pm (UTC) - Expand
Re: try this shit - polachok - Feb. 11th, 2016 10:47 pm (UTC) - Expand
Re: try this shit - polachok - Feb. 11th, 2016 11:19 pm (UTC) - Expand
Re: try this shit - dmzlj - Feb. 12th, 2016 08:34 am (UTC) - Expand
Re: try this shit - Евгений Храмцов - Feb. 12th, 2016 09:16 am (UTC) - Expand
Re: try this shit - Евгений Храмцов - Feb. 12th, 2016 09:18 am (UTC) - Expand
Re: try this shit - lionet - Feb. 12th, 2016 09:57 am (UTC) - Expand
(no subject) - polachok - Feb. 11th, 2016 07:03 pm (UTC) - Expand
Maxim Velesyuk
Feb. 12th, 2016 09:54 am (UTC)
На ниме вариант:

var sum: int64 = 0
for e in countup(0, 200-1):
    sum = 0
    var x: seq[int] = @[]

    for i in countup(0, 1000000-1):
        x.add(i)

    var y: seq[int] = @[]
    for i in countup(0, 1000000-2):
        y.add(x[i] + x[i+1])

    for i in countup(0, 1000000-1, 100):
        sum += y[i];
    
echo(sum)


> ~/dev/Nim/bin/nim --version                                                                                                                                                                                               Fri 12 Feb 2016 12:48:48 PM MSK
Nim Compiler Version 0.13.0 (2016-02-12) [Linux: amd64]
Copyright (c) 2006-2015 by Andreas Rumpf

git hash: a121c3f9eb2a348b9d6ae03ffd01aab26a238c30
active boot switches: -d:release

> ~/dev/Nim/bin/nim c -d:release test

> time ./test                      
9999010000
2.53user 2.80system 0:05.36elapsed 99%CPU (0avgtext+0avgdata 33484maxresident)k
0inputs+0outputs (0major+2551751minor)pagefaults 0swaps                              

> time ./test-go
9999010000
5.79user 0.33system 0:04.33elapsed 141%CPU (0avgtext+0avgdata 65292maxresident)k
0inputs+0outputs (0major+16069minor)pagefaults 0swaps                                                                                                                                                                                 


Я в плюсах не очень шарю, подскажите как скомпилить плюсовый вариант, у меня gcc-5.2.0, ругается на типы:
test.cpp: In function ‘int main()’:
test.cpp:5:5: error: ‘int64_t’ was not declared in this scope
     int64_t sum = 0;
     ^

lionet
Feb. 12th, 2016 09:58 am (UTC)
#include stdint.h or inttypes.h, or sys/types.h.

Or just replace it with long, that's the same size if your platform is 64-bit.
(no subject) - udpn - Feb. 12th, 2016 08:16 pm (UTC) - Expand
(no subject) - thedeemon - Feb. 12th, 2016 10:42 am (UTC) - Expand
(no subject) - Maxim Velesyuk - Feb. 12th, 2016 12:37 pm (UTC) - Expand
(no subject) - udpn - Feb. 12th, 2016 08:15 pm (UTC) - Expand
Maxim Velesyuk
Feb. 12th, 2016 09:51 pm (UTC)
We have a special guest here ;)
(defun test ()
  (declare (optimize (speed 3) (debug 0) (safety 0)))
  (let ((sum 0))
    (declare (fixnum sum))
    (loop for e from 0 upto (1- 200)
       for x = (make-array '(0) :element-type 'fixnum
                           :adjustable t :fill-pointer t)
       for y = (make-array '(0) :element-type 'fixnum
                           :adjustable t :fill-pointer t)
       do (progn
            (setf sum 0)
            (loop for i from 0 upto (1- 1000000)
               do (vector-push-extend i x))
            (loop for i from 0 upto (- 1000000 2)
               do (vector-push-extend
                   (+ (aref x i)
                      (aref x (1+ i)))
                   y))
            (loop for i from 0 upto (1- 1000000) by 100
               do (incf sum (aref y i))))
       finally (return sum))))

* (time (test))

Evaluation took:
  14.916 seconds of real time
  14.902000 seconds of total run time (14.235000 user, 0.667000 system)
  [ Run times consist of 0.465 seconds GC time, and 14.437 seconds non-GC time. ]
  99.91% CPU
  37,205,725,473 processor cycles
  6,706,393,760 bytes consed

9999010000


BTW any ideas how to optimize this even better?

Edited at 2016-02-12 09:57 pm (UTC)
lionet
Feb. 12th, 2016 10:06 pm (UTC)
"Even better"? Looks pretty shitty to me to begin with... You might have meant "to optimize" ;)

I don't know. Ask Nikita?
(no subject) - Maxim Velesyuk - Feb. 12th, 2016 11:22 pm (UTC) - Expand
(no subject) - lionet - Feb. 15th, 2016 06:08 am (UTC) - Expand
(no subject) - tonsky - Feb. 15th, 2016 10:01 am (UTC) - Expand
(no subject) - Maxim Velesyuk - Mar. 25th, 2016 10:51 pm (UTC) - Expand
tonsky
Feb. 15th, 2016 10:48 am (UTC)
Java (with preallocation):

class Bench {
  
  public static long bench() {
    long sum = 0;
    int size = 100000;
    long t0 = System.nanoTime();
    
    for(int e = 0; e < 2000; e++) {
        sum = 0;

        long[] x = new long[size];
        for(int i = 0; i < size; i++) {
            x[i] = i;
        }

        long[] y = new long[size];
        for(int i = 0; i < size-1; i++) {
            y[i] = x[i] + x[i+1];
        }

        for (int i = 0; i < size; i += 100) {
            sum += y[i];
        }
    }
    System.out.println(sum + " in " + (System.nanoTime() - t0)/1000000 + "ms");
    return sum;
  }
  
  public static void main(String[] args) {
    for(int i=0; i<10; ++i) {
      bench();
    }
  }
}


[~/work/lionet_bench] javac Bench.java && time java -server -Xmx4g -Xms4g Bench
99901000 in 933ms
99901000 in 526ms
99901000 in 873ms
99901000 in 681ms
99901000 in 722ms
99901000 in 668ms
99901000 in 679ms
99901000 in 674ms
99901000 in 663ms
99901000 in 665ms

Takes some time for JIT to kick in, though

C++ baseline (with added vector.reserve() to be on par with java):

[~/work/lionet_bench] c++ -O3 bench.cpp && time ./a.out
99901000

real 0m0.843s
user 0m0.834s
sys 0m0.004s
tonsky
Feb. 15th, 2016 11:17 am (UTC)
По-хорошему надо бы и у С++ вычесть startup time, но я почитал C++ форум про «Easily measure elapsed time» и у меня из глаз кровь полилась, потом и они сами выпали, и ковер на стене загорелся.
(no subject) - tonsky - Feb. 15th, 2016 11:22 am (UTC) - Expand
(no subject) - ulysses4ever - Jul. 31st, 2016 07:49 pm (UTC) - Expand
(no subject) - lionet - Feb. 16th, 2016 04:01 am (UTC) - Expand
(no subject) - tonsky - Feb. 16th, 2016 09:01 am (UTC) - Expand
(no subject) - lionet - Feb. 16th, 2016 10:13 am (UTC) - Expand
(no subject) - tonsky - Feb. 16th, 2016 05:41 pm (UTC) - Expand
(no subject) - lionet - Feb. 16th, 2016 08:36 pm (UTC) - Expand
(no subject) - tonsky - Feb. 16th, 2016 09:27 pm (UTC) - Expand
(no subject) - lionet - Feb. 17th, 2016 10:29 am (UTC) - Expand
(Deleted comment)
lionet
Feb. 24th, 2016 05:29 am (UTC)
Олег... внимательнее!

1. (0..200) это не (0..199)
2. $x[i] должен был быть $x[$i]
3. for my $i (0..1000000) должен был быть for my $i (0..1000000-1).

[vlm@nala:~]> cat test.pl 
#!/usr/bin/env perl

use strict;

my $sum = 0;

foreach my $e (0..199) {
    $sum = 0;

    my @x = ();
    for (my $i = 0; $i < 1000000; $i++) {
        push @x, $i;
    }

    my @y = ();
    for (my $i = 0; $i < 1000000-1; $i++) {
        push @y, ($x[$i] + $x[$i+1]);
    }

    for (my $i = 0; $i < 1000000; $i += 100) {
        $sum += $y[$i];
    }
}

print "$sum\n";

[vlm@nala:~]> time ./test.pl 
9999010000

real	1m47.273s
user	1m47.140s
sys	0m0.106s
[vlm@nala:~]> 
(no subject) - Andrey Kovbovich - Feb. 25th, 2016 03:58 pm (UTC) - Expand
Igor Milyakov
Feb. 25th, 2016 12:54 am (UTC)
With profile-generate + profile-use and DNDEBUG=1 you can get it run even faster:


[virtan@kong ~/tmp] time ./tsd
9999010000

real 0m0.672s
user 0m0.662s
sys 0m0.008s
Andrey Kovbovich
Feb. 25th, 2016 04:20 pm (UTC)
ocaml
Если оптимизировать работу с int array наподобие float array, получим такие вот тайминги:

$ time OCAMLRUNPARAM=s=4M,i=32M,o=150 ./test-ocaml
9999010000

real	0m1.152s
user	0m1.071s
sys	0m0.077s

$ time ./test-rust
9999010000

real	0m1.661s
user	0m0.692s
sys	0m0.961s

$ time ./test-c
9999010000

real	0m2.780s
user	0m1.471s
sys	0m1.296s

$ time ./test-go
9999010000

real	0m4.421s
user	0m3.735s
sys	0m0.304s

ocamlopt -inline 100 intarray.c -o test-ocaml bench_ocaml.ml

$ cat bench_ocaml.ml
module Array = struct
  include Array
  external create_int : int -> int array = "caml_array_make_int_vect"
  external unsafe_blit_int : int array -> int -> int array -> int -> int -> unit = "caml_array_unsafe_blit_int"
end

module Dynarray : sig
  type t
  val create : unit -> t
  val get    : t -> int -> int
  val add    : t -> int -> unit
end = struct
  type t = { mutable arr : int array; mutable len : int }

  let create () = { arr = Array.create_int 0; len = 0 }

  let expand t n =
    let new_arr = Array.create_int (n * 2) in
    Array.unsafe_blit_int t.arr 0 new_arr 0 (n - 1);
    t.arr <- new_arr;
    t.len <- n

  let get t i = Array.unsafe_get t.arr i

  let add t x =
    if t.len = Array.length t.arr then expand t (t.len + 1) else t.len <- t.len + 1;
    Array.unsafe_set t.arr (t.len - 1) x
end

module D = Dynarray

let () =
  let sum = ref 0 in

  for e=0 to 200-1 do
    sum := 0;

    let x = D.create () in
    for i=0 to 1000000-1 do
      D.add x i
    done;

    let y = D.create () in
    for i=0 to 1000000-2 do
      D.add y (D.get x i + D.get x (i+1))
    done;

    let i = ref 0 in
    while !i < 1000000 do
      sum := !sum + D.get y !i;
      i := !i + 100
    done
  done;

  Printf.printf "%d\n" !sum

$ cat intarray.c
#include <string.h>
#include "caml/memory.h"
#include "caml/mlvalues.h"

CAMLprim value caml_array_unsafe_blit_int(value a1, value ofs1, value a2, value ofs2,
                                          value n)
{
    memmove(&Field(a2, Long_val(ofs2)),
            &Field(a1, Long_val(ofs1)),
            Long_val(n) * sizeof(value));
    return Val_unit;
}

CAMLprim value caml_array_make_int_vect(value len)
{
  mlsize_t wosize = Long_val(len) * sizeof(value);
  value result;
  if (wosize == 0)
    return Atom(0);
  else {
    result = caml_alloc_shr (wosize, 0);
    result = caml_check_urgent_gc (result);
  }
  return result;
}


Edited at 2016-02-25 06:26 pm (UTC)
lionet
Feb. 26th, 2016 06:44 am (UTC)
Re: ocaml
Re: ocaml - Yuzhe Yan - Oct. 5th, 2016 02:15 am (UTC) - Expand
Re: ocaml - lionet - Oct. 5th, 2016 05:22 am (UTC) - Expand
zevlg
Jan. 16th, 2017 12:38 pm (UTC)
а pony запусти ещё:

use "collections"

actor Main
  new create(env: Env) =>
    var x = Array[U64]
    var y = Array[U64]
    var sum: U64 = 0

    for e in Range(0, 200) do
    try
      for i in Range[U64](0, 1000000) do
        x.push(i)
      end
  
      for i in Range(0, 1000000-1) do
        y.push(x(i) + x(i+1))
      end
  
      for i in Range(0, 1000000, 100) do
        sum = sum + y(i)
      end
    end
    end

    env.out.print(sum.string())


Edited at 2017-01-16 12:56 pm (UTC)
( 86 comments — Leave a comment )

Profile

lionet
Lev Walkin
Website

Latest Month

December 2016
S M T W T F S
    123
45678910
11121314151617
18192021222324
25262728293031
Powered by LiveJournal.com
Designed by yoksel