More interesting languages for arena, only briefly tested.

Perl (reference)


#!/usr/bin/perl
$|=1;   #disable output buffering, this is necessary for proper output through pipe
use strict;

my $str = 'abcdefgh'.'efghefgh';
my $imax = 1024/length($str)*1024*4;      # 4mb

my $starttime = time();
print "exec.tm.sec\tstr.length\n";

my $gstr = '';
my $i = 0;

while($i++ < $imax+1000){   #adding 1000 iterations to delay exit. This will allow to capture memory usage on last step
    $gstr .= $str;
    $gstr =~ s/efgh/____/g;
    my $lngth = length($str) * $i;  ##  my $lngth=length($gstr);    # Perhaps that would be a slower way
    if (0 == $lngth % (1024*256)){    #print out every 256kb
        print time()-$starttime," sec\t\t",$lngth/1024,"kb\n";
    }
}
#print $gstr,"\n";
$ perl --version
This is perl 5, version 28, subversion 0 (v5.28.0) built for x86_64-linux-gnu-thread-multi
exec.tm.sec     str.length
0 sec           256kb
2 sec           512kb
5 sec           768kb
9 sec           1024kb
15 sec          1280kb
21 sec          1536kb
29 sec          1792kb
38 sec          2048kb
49 sec          2304kb
61 sec          2560kb
75 sec          2816kb
91 sec          3072kb
109 sec         3328kb
129 sec         3584kb
152 sec         3840kb
177 sec         4096kb

Used under 100% of CPU;
Resident RAM usage: up to 17M.

Very good.


Perl6


#!/usr/bin/perl6

use v6;

$*OUT.out-buffer=False;   #disable output buffering, this is necessary for proper output through pipe
use strict;

my $str = 'abcdefgh' ~ 'efghefgh';
my $imax = 1024 / chars($str) * 1024 * 4;      # 4mb

#dd DateTime.now.Instant;
my $starttime = DateTime.now.Instant.Int();
print "exec.tm.sec\tstr.length\n";

my $gstr='';
my $i=0;

while $i++ < $imax+1000 {   #adding 1000 iterations to delay exit. This will allow to capture memory usage on last step
    $gstr ~= $str;
    $gstr ~~ s:g/efgh/____/;
    my $lngth = chars($str) * $i;  ##  my $lngth=length($gstr);    # Perhaps that would be a slower way
    if 0 == $lngth % (1024*256) {    #print out every 256kb
        say DateTime.now.Instant.Int()-$starttime, " sec\t\t", $lngth/1024, "kb";
    }
}
#print $gstr,"\n";
$ perl6 --version
This is Rakudo version 2018.09 built on MoarVM version 2018.09
exec.tm.sec     str.length
10 sec          256kb
38 sec          512kb
79 sec          768kb
131 sec         1024kb
198 sec         1280kb
287 sec         1536kb
384 sec         1792kb
502 sec         2048kb
637 sec         2304kb
796 sec         2560kb
958 sec         2816kb
1137 sec        3072kb
1323 sec        3328kb
1523 sec        3584kb
1747 sec        3840kb
1978 sec        4096kb

Used 100% CPU;
Resident RAM usage: up to 13600M.

1117% of Perl time, 11 times slower with insane memory footprint.

Beautiful but unusable language...


Julia


#!/usr/bin/julia

const str = raw"abcdefgh" * raw"efghefgh"

function arena_bench()
    imax = 1024 / length(str) * 1024 * 4     # 4mb

    println("exec.tm(sec)\t\tstr.length(kb)")

    starttime = time()
    gstr = ""

    for i = 1: imax+1000    # adding 1000 iterations to delay exit. This will allow to capture memory usage on last step
        gstr *= str
        gstr = replace(gstr, r"efgh" => "____")

        lngth::Int = length(str) * i
        if 0 == lngth % (1024 * 256)     ## print out every 256kb
            println( trunc(Int, time() - starttime), "\t\t\t", trunc(Int, lngth/1024) )
        end
    end

#    println(gstr)
end

arena_bench()

$ julia --version
julia version 1.0.1
exec.tm(sec)            str.length(kb)
1                       256
7                       512
17                      768
29                      1024
46                      1280
67                      1536
92                      1792
129                     2048
164                     2304
202                     2560
244                     2816
292                     3072
350                     3328
417                     3584
489                     3840
569                     4096

Used 100% CPU;
Resident RAM usage: up to 230M.

320% of Perl time, 3 times slower.

Could have been better.


Golang


package main

import (
    "fmt"
    "regexp"
    "time"
)

func main() {
    const str = "abcdefgh" + "efghefgh"
    var imax = 1024 / len(str) * 1024 * 4 // 4mb

    var starttime = time.Now()
    fmt.Printf("exec.tm.sec\tstr.length\n")

    var gstr = ""
    var lngth int
    re := regexp.MustCompile("efgh")

    for i := 1; i <= imax+1000; i++ { // adding 1000 iterations to delay exit. This will allow to capture memory usage on last step
        gstr += str
        gstr = re.ReplaceAllString(gstr + str, "____")
        lngth = len(str) * i
        if 0 == lngth%(1024 * 256) { // print out every 256kb
            t := time.Now()
            fmt.Printf("%.0f sec\t\t%d kb\n", t.Sub(starttime).Seconds(), lngth/1024)
        }
    }
//  fmt.Println(gstr)
}
$ go version
go version go1.10.4 linux/amd64
exec.tm.sec     str.length
2 sec           256 kb
10 sec          512 kb
22 sec          768 kb
39 sec          1024 kb
59 sec          1280 kb
89 sec          1536 kb
127 sec         1792 kb
166 sec         2048 kb
209 sec         2304 kb
265 sec         2560 kb
329 sec         2816 kb
399 sec         3072 kb
481 sec         3328 kb
564 sec         3584 kb
662 sec         3840 kb
764 sec         4096 kb

Used over 150% of CPU (up to 200%), due to garbage collection.
Resident RAM usage: 190M.

431% of Perl time, 4 times slower.

Disappointing performance, and RAM usage; slow regex library.


Rust


use std::time::{Instant};
extern crate regex;
use regex::Regex;

// https://github.com/rust-lang/rust/issues/23818
use std::io::prelude::*;
use std::io;

fn main() {
    let strr = "abcdefgh".to_owned() + "efghefgh";
//  let strr = concat!(r"abcdefgh", r"efghefgh");

    let imax = 1024 / strr.len() * 1024 * 4;     // 4mb

    let starttime = Instant::now();
    println!("exec.tm.sec\tstr.length");

    let mut gstr = String::new();
    let mut lngth;

    let re = Regex::new(r"efgh").unwrap();

    let mut i = 0;
    while i < imax+1000 { // adding 1000 iterations to delay exit. This will allow to capture memory usage on last step
        i += 1;

//      gstr += &strr;  // Seems to be a little slower than push_str
        gstr.push_str(&strr);

        gstr = re.replace_all( &gstr, "____" ).to_string();

        lngth = strr.len() * i;
//      lngth = gstr.len();

        if 0 == lngth % (1024 * 256) { // print out every 256kb
            let timenow = Instant::now();
            println!("{:?} sec\t\t{} kb", timenow.duration_since(starttime).as_secs(), lngth/1024);
            io::stdout().flush().ok().expect("Could not flush stdout"); //works
        }
    }
//println!("{}", gstr);
}
$ rustc --version
rustc 1.28.0
exec.tm.sec     str.length
0 sec           256 kb
2 sec           512 kb
4 sec           768 kb
9 sec           1024 kb
13 sec          1280 kb
17 sec          1536 kb
23 sec          1792 kb
32 sec          2048 kb
43 sec          2304 kb
52 sec          2560 kb
63 sec          2816 kb
75 sec          3072 kb
89 sec          3328 kb
106 sec         3584 kb
125 sec         3840 kb
149 sec         4096 kb

Used 100% CPU;
Resident RAM usage: up to 20M.

Only 84% of Perl time. Small memory footprint.

Excellent. Rust is the winner.


Donations are much appreciated.