view slides/2018/07/17/slide.md @ 49:49a9086fc7e9

auto-Update generated slides by script
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Tue, 31 Jul 2018 18:28:00 +0900
parents
children
line wrap: on
line source

title: CbCによるMoarVMの改良
author: Takahiro Shimizu
profile:
lang: Japanese


# 研究目的
- Perl5の後継言語として開発されているPerl6はMoarVMと呼ばれるVMを搭載している.
- Perl6はMoarVM,JVM,JavaScript上で動くRakudoと呼ばれる実装と,コンパイラ開発者用のサブセットであるNQPが主な実装となっている.
- 現在Perl6及びMoarVMは全体的な速度がPerl5と比較し低下しており,実務として利用できるレベルに達していない.
- さらにPerl6の実装自体巨大なcase-switch文など見通しが悪くなっている.
- この問題を解決するために現在当研究室で開発している継続を中心にしたContinuation based Cを用いて改良を行う
- CbCの設計理念からVMの実装と親和性が高い事も推測できる為,実際にCbCを用いてどのようにVMが実装できるかを検証する

# 今週の進捗

* JVM版Perl6をBuildしました
* logアナライザーを作成して時間計測を行いました
* 院試出願しました
* 趣味でPerl2をbuildしてます

# ログアナライザー(Perl5)

```perl5
#!/usr/bin/env perl
use strict;
use warnings;
use Time::HiRes qw/gettimeofday tv_interval/;

my $t0 = [gettimeofday];

my $file = "/var/log/system.log";

if(@ARGV == 2){
    if ( $ARGV[0] eq "-f"){
        $file = $ARGV[1];
    }
}

my $user_name = qr/anatofuzMBP|anatofuz-15/;
open my $fh, "<",$file;
my $count = {};

while (my $line = <$fh>) {
    if ( $line =~ /\w \d{0,2} (?:\d{2}:?){3} $user_name ([\w.]+)\[\d+\]/){
        $count->{$1}++;
    }
}

my $sum = 0;

for my $key (keys %$count){
    $sum += $count->{$key};
}

print "$sum\n";
my $t1 = [gettimeofday];

my $evec_time = tv_interval($t0,$t1);
print "$evec_time\n";

```

# ログアナライザー(Ruby)

```ruby
#!/usr/bin/env ruby

require 'benchmark'

result = Benchmark.realtime do
    file = "/var/log/system.log"

    user_name = Regexp.new("anatofuzMBP|anatofuz-15")
    count = Hash.new(0)

    File.open(file,'r') do |f|
        f.each_line do |line|
            if line =~ /\w+ \d{0,2} (?:\d{2}:?){3} #{user_name} ([\w.]+)\[\d+\]/
                count[$1] += 1
            end
        end
    end


    sum = 0

    for key in count.keys
        sum += count[key]
    end

    p sum
end
#p "#{Time.now - start_time}"
puts "#{result}"

```

# ログアナライザー(Perl6)

```perl6
#!/usr/bin/env perl
use v6;

my $start = DateTime.now;

unit sub MAIN(:f($file) where { .IO.f } = '/var/log/system.log');

my $user_name = /'anatofuzMBP'|'anatofuz-15'/;
my $fh = open $file,:r;
my %count =();

for $fh.lines -> $line {
     if ( $line ~~ /\w+ \s \d**0..3 \s [\d**2\:?]**3 \s $user_name \s (<[\w.]>+)\[\d+\]/) {
         %count{$0}++;
    }
}
$fh.close;
my $sum = 0;

for %count.keys -> $key {
    $sum += %count{$key};
}

$sum.say;

my $end = DateTime.now;

my $time = $end - $start;
say $time;

```

# ログアナライザー(Python)

```python
#!/usr/bin/env python
import re
import sys
from collections import defaultdict
import time

start_time  = time.time()

file_path = "/var/log/system.log"
args = sys.argv

if args == 3:
    if args[1] == "-f":
        file_path = args[2]

count = defaultdict(int)

with open(file_path) as f:
    for line in f:
        match = re.search(r'\w+ \d{0,2} (?:\d{2}:?){3} (?:anatofuzMBP|anatofuz-15) ([\w.]+)\[\d+\]',line)
        if match:
            count[match.group(1)]+=1

total = 0

for key in count.keys():
    total +=count[key]

print(total)

end_time = time.time()

print(end_time - start_time)

```

# ログアナライザー(java)

```java
package com.google.anatofuz;

import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class LogAnalyzer {

    public static void main(String args[]) {

        long start = System.currentTimeMillis();
        File file = new File("/var/log/system.log");

        if (args.length != 0) {
            if (args[0].equals("-f")) {
                file = new File(args[1]);
            }
        }

        try {
            FileReader filereader = new FileReader(file);
            BufferedReader bufferedReader = new BufferedReader(filereader);

            String line;
            Map<String,Integer>  map = new HashMap<String,Integer>(0);
            Pattern p = Pattern.compile("\\w+ \\d{0,2} (?:\\d{2}:?){3} (?:anatofuzMBP|anatofuz-15) ([\\w.]+)\\[\\d+\\]");


            while ((line = bufferedReader.readLine()) != null) {
                Matcher matcher = p.matcher(line);
                if (matcher.find()) {
                    map.merge(matcher.group(1),1,Integer::sum);
                }
            }

            int sum = 0;

            for (String key :map.keySet()){
                sum += map.get(key);
            }

            System.out.println(sum);

            long end = System.currentTimeMillis();

            System.out.println("0.0" + (end - start));

        } catch (FileNotFoundException ex){
            System.out.println(ex);
        } catch (IOException ex){
            System.out.println(ex);
        }
    }
}

```

# 計測結果

* 結果をブログに載せたら起動時間の比較と突っ込まれる

```
perl6(moar)
950
/Users/anatofuz/workspace/cr/Basic/build_perl6/bin/perl6 log_analyze.p6  0.94s user 0.05s system 128% cpu 0.769 total

perl6(jvm)
./perl6 ~/workspace/cr/Basic/perl6/sandbox/log/log_analyze.p6  17.51s user 0.61s system 439% cpu 4.118 total


perl5
950
perl log_analyze.pl  0.04s user 0.04s system 86% cpu 0.098 total

ruby
950
ruby log_analyze.rb  0.16s user 0.06s system 92% cpu 0.243 total

java
java -jar java/build/libs/anatofuz-1.0-SNAPSHOT.jar  0.27s user 0.05s system 149% cpu 0.212 total

time python log_analyze.py
python log_analyze.py  0.07s user 0.05s system 77% cpu 0.153 total
```



# 内部処理

* 内部処理時間のみ計測
* perl5 
    * 0.003434s
* Ruby
    * 0.046458s
* Python
    * 0.0097
* Java
    * 0.047
* Perl6(Moar)
    * 0.2649
* Perl6(JVM)
    * 0.687

```
perl5
0.003434
perl log_analyze.pl  0.04s user 0.04s system 76% cpu 0.105 total

=====
ruby
0.04645899997558445
ruby log_analyze.rb  0.15s user 0.05s system 85% cpu 0.239 total
=====

python log_analyze.py 
0.009788036346435547

=====

java
0.047
java -jar java/build/libs/anatofuz-1.0-SNAPSHOT.jar  0.27s user 0.05s system 151% cpu 0.209 total

=====
perl6
0.2649038
/Users/anatofuz/workspace/cr/Basic/build_perl6/bin/perl6 log_analyze.p6  0.86s user 0.08s system 109% cpu 0.856 total

=====
perl6(jvm)
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.perl6.nqp.runtime.Ops (file:/Users/anatofuz/workspace/cr/Basic/jvm/nqp/install/share/nqp/runtime/nqp-runtime.jar) to field sun.management.RuntimeImpl.jvm
WARNING: Please consider reporting this to the maintainers of org.perl6.nqp.runtime.Ops
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
0.687
/Users/anatofuz/workspace/cr/Basic/jvm/rakudo/perl6   21.48s user 0.72s system 436% cpu 5.087 total

```


# 院試

* 出願しました
* 過去問やってます

# Perl2

* Perl5のgitリポジトリにtagとして残っていました
* gcc/cc1でbuild出来るようにパッチを書いてます
   * gccを参照するように変更
   * `<command-line>`というヘッダーファイルを削除
   * `sprintf`などの関数の返り値を修正
   * yaccのシンタックスエラーを解消