Ada, Go, Erlang, Scala, Stackless Python, Java (java.util.concurrent), シェルスクリプトの適当すぎる比較

同じようなコードをそれぞれの言語で書いてみた。

Ada:

with Ada.Text_IO;
with Ada.Strings.Unbounded;

procedure MyTest is
    use Ada.Strings.Unbounded;
    use Ada.Text_IO;

    task MyTask is
        entry Hello(Message: String);
    end;

    task body MyTask is
        Received_Message: Unbounded_String;
    begin
        loop
            select
                accept Hello(Message: in String) do
                    Received_Message := To_Unbounded_String(Message);
                end Hello;
            end select;
            Put_Line(To_String(Received_Message));
        end loop;
    end;

    package IIO is new Integer_IO(Integer);

    Count: Integer := 0;
    Tmp: String(1 .. Integer'Width);
begin
    loop
        IIO.Put(Tmp, Count);
        MyTask.Hello(Tmp);
        delay 1.0;
        Count := Count + 1;
    end loop;
end;

Go:

package main

import (
    "fmt";
    "strconv";
    "time"
)

func MyTask(ch chan string) {
    for {
        received_message := <- ch;
        fmt.Printf("%s\n", received_message)
    }
}

func main() {
    count := 0;
    ch := make(chan string);
    go MyTask(ch);
    for {
        ch <- strconv.Itoa(count);
        time.Sleep(1000000000);
        count += 1
    }
}

Erlang:

-module(mytest).
-export([main/0, mytask/0]).
-import(io).
-import(timer).

mytask() ->
    receive
        Message -> io:format("~s~n", [Message])
    end,
    mytask().

main_loop(T, Count) ->
    T ! integer_to_list(Count),
    timer:sleep(1000),
    main_loop(T, Count + 1).

main() ->
    main_loop(spawn(?MODULE, mytask, []), 0).

Scala:

import scala.actors.Actor._;

object mytest {
    val MyTask = actor {
        while (true) {
            receive {
                case value => println(value)
            }
        }
    }

    def main(args: Array[String]) = {
        var count = 0
        while (true) { 
            MyTask ! count.toString;
            count += 1;
            Thread.sleep(1000);
        }
    }
}

Stackless Python:

import time
from stackless import channel, tasklet, run

def mytask(ch):
    while True:
        print ch.receive()

def main():
    ch = channel()

    tasklet(mytask)(ch)
    run()

    count = 0
    while True:
        ch.send(str(count))
        time.sleep(1)
        count += 1

if __name__ == '__main__':
    main()

Java:

import java.util.concurrent.*;

public class MyTest {
    private static class MyTask implements Runnable {
        public MyTask(BlockingQueue<String> ch) {
            this.ch = ch;
        } 

        public void run() {
            try {
                for (;;) {
                    System.out.println(ch.take());
                }
            } catch (InterruptedException e) {}
        }

        private BlockingQueue<String> ch;
    }

    public static void main(String[] args) throws Exception {
        ArrayBlockingQueue<String> abq = new ArrayBlockingQueue<String>(10);
        new Thread(new MyTask(abq)).start();
        int count = 0;
        for (;;) {
            abq.put(Integer.toString(count));
            Thread.sleep(1000);
            count++;
        }
    }
}

魔改造PHP:

<?php
function mytask($ch) {
    for (;;) {
        $msg = <- [$ch];
        echo $msg, "\n";
    } 
}

$ch = thread_message_queue_create();
thread_create('mytask', $ch);

$count = 0;
for (;;) {
    [$ch] <- $count++;
    sleep(1);
}
?> 

Bourne Shell:

#!/bin/sh

mytask() {
    while true; do
        cat "$fifo"
    done
}

int_hdlr() {
    rm -rf "$tmpdir"
    exit 0
}

tmpdir=`mktemp -d`

fifo=$tmpdir/fifo
mkfifo $fifo

trap int_hdlr INT

mytask &
count=0
while true; do
    echo $count > $fifo
    sleep 1
    count=`expr $count + 1`
done

※比較は各自行ってください。