Sunday, July 18, 2010

Two Performance Tests

Just two performance tests. I thought it would be nice just to show off with some source code. No difficult type-class/interface stuff here, just performance tests I made.


// test ackermann 3 n
import "system.hi"

using system

def ack: int -> int -> int =
    [ 0, n -> n + 1
    | m, 0 -> ack (- 1) 1
    | m, n -> ack (- 1) (ack m (- 1)) ]

def main: unit =
    c = argc nop;
    n = text_to_int (argv (c-1));
    _ = print (ack 3 n);
        nop

// invert nucleotides from a file in Fasta format
import "system.hi"

using system

def complement: char -> char =
    [ 'A' -> 'T' | 'a' -> 'T'
    | 'C' -> 'G' | 'c' -> 'G'
    | 'G' -> 'C' | 'g' -> 'C'
    | 'T' -> 'A' | 't' -> 'A'
    | 'U' -> 'A' | 'u' -> 'A'
    | 'M' -> 'K' | 'm' -> 'K'
    | 'R' -> 'Y' | 'r' -> 'Y'
    | 'W' -> 'W' | 'w' -> 'W'
    | 'S' -> 'S' | 's' -> 'S'
    | 'Y' -> 'R' | 'y' -> 'R'
    | 'K' -> 'M' | 'k' -> 'M'
    | 'V' -> 'B' | 'v' -> 'B'
    | 'H' -> 'D' | 'h' -> 'D'
    | 'D' -> 'H' | 'd' -> 'H'
    | 'B' -> 'V' | 'b' -> 'V'
    | 'N' -> 'N' | 'n' -> 'N'
    | c   -> c   ]

def complement_code: int -> int =
    [ n -> 
        c = complement (char_ascii_char n);
        char_ascii_code c ]

def ascii_n : int = char_ascii_code '\n'
def ascii_s : int = char_ascii_code ';'
def ascii_l : int = char_ascii_code '<'

def copy_line: file -> file -> unit =
    [ i, o ->
        n = fgetc i;
        if n < 0 then nop
        else if n == ascii_n then 
            _ = fputc o n;
                process_lines i o
        else 
            _ = fputc o n;
                copy_line i o ]

def reverse_line: file -> file -> unit =
    [ i, o ->
        n = fgetc i;

        if n < 0 then nop
        else if n == ascii_n then 
            _ = fputc o n;
                process_lines i o
        else 
            n = complement_code n;
            _ = fputc o n;
                reverse_line i o ]

def process_lines: file -> file -> unit =
    [ i, o ->
        n = flookc i;
        if n < 0 then nop
        else if n == ascii_s then
            copy_line i o
        else if n == ascii_l then
            copy_line i o
        else reverse_line i o ]

def main: unit =
    i = get_stdin nop;
    o = get_stdout nop;
        process_lines i o


With full optimization, the first program, ackermann 3 8, runs in somewhat more than eight seconds on a 2.26GHz Macbook Pro (not sure when the 2.26 kicks in). Anyway, that is slow, it's Python speed. I blogged on it before, most of the time is spend on resolving dynamic symbols, calling C, resolving overloading, and subsequently, garbage collecting the heap from all thunks inserted to do all that work. I think, with some optimization, I could get it down to 1-3 seconds, which would be fine by me. (Most work in my compiler is just plain graph rewriting, which is the one thing not tested by most performance tests.)

The second, reversal of nucleotides, I didn't really test yet on real input data. Just some short files made by me to check if it works. No performance comparisons yet. (I tested the "it can handle infinite recursion" feature by piping an infinite stream of data, "ACTG" strings, to it, it performs ok. See if I can get my hands on some real test-data.)

No comments:

Post a Comment