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.