/* test-perf.vala
 *
 * Copyright (C) 2008 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
 *
 * Licensed under GPLv2.
 *
 * A simple test app to compare the time it takes to create instances of struct,
 * compact class, class and class deriving from GLib.Object in Vala.
 *
 * Compile using: valac -o test-perf --pkg gstreamer-0.10 test-perf.vala
 *
 */

struct Struct {
    public uint f1;
    public double f2;
}

[Compact]
class CompactClass {
    public uint f1;
    public double f2;

    CompactClass (uint f1, double f2) {
        this.f1 = f1;
        this.f2 = f2;
    }
}

class Class {
    public uint f1;
    public double f2;

    Class (uint f1, double f2) {
        this.f1 = f1;
        this.f2 = f2;
    }
}

class MiniClass : Gst.MiniObject {
    public uint f1;
    public double f2;

    MiniClass (uint f1, double f2) {
        this.f1 = f1;
        this.f2 = f2;
    }
}

class OClass : Object {
    public uint f1;
    public double f2;

    public static OClass instantiate (uint f1, double f2) {
        OClass obj = new OClass ();
        obj.f1 = f1;
        obj.f2 = f2;

        return obj;
    }
}

class Test.Perf {
    static const uint NUM_INSTANCES = 1048576;

    // Create some instances to get rid of any first-time creation time
    Class aclass = new Class (0, 0.0);
    CompactClass acompactclass = new CompactClass (0, 0.0);
    OClass aoclass = OClass.instantiate (0, 0.0);

    Timer timer = new Timer();

    public void test_struct () {
        Struct[] structs = new Struct[NUM_INSTANCES];

        // Reset timer
        this.timer.start ();
        for (int i = 0; i < NUM_INSTANCES; i++) {
            structs[i].f1 = 0;
            structs[i].f2 = 0.0;
        }

        print ("%f seconds taken in creating %u structs.\n",
               timer.elapsed (),
               NUM_INSTANCES);
    }

    public void test_class () {
        Class[] classes = new Class[NUM_INSTANCES];

        // Reset timer
        this.timer.start ();
        for (int i = 0; i < NUM_INSTANCES; i++) {
            classes[i] = new Class (0, 0.0);
        }

        print ("%f seconds taken in creating %u instances.\n",
               timer.elapsed (),
               NUM_INSTANCES);
    }

    public void test_compact_class () {
        CompactClass[] classes = new CompactClass[NUM_INSTANCES];

        // Reset timer
        this.timer.start ();
        for (int i = 0; i < NUM_INSTANCES; i++) {
            classes[i] = new CompactClass (0, 0.0);
        }

        print ("%f seconds taken in creating %u instances (compact).\n",
               timer.elapsed (),
               NUM_INSTANCES);
    }

    public void test_mini_class () {
        MiniClass[] classes = new MiniClass[NUM_INSTANCES];

        // Reset timer
        this.timer.start ();
        for (int i = 0; i < NUM_INSTANCES; i++) {
            classes[i] = new MiniClass (0, 0.0);
        }

        print ("%f seconds taken in creating %u instances (GstMiniObject).\n",
               timer.elapsed (),
               NUM_INSTANCES);
    }

    public void test_oclass () {
        OClass[] classes = new OClass[NUM_INSTANCES];

        // Reset timer
        this.timer.start ();
        for (int i = 0; i < NUM_INSTANCES; i++) {
            classes[i] = OClass.instantiate (0, 0.0);
        }

        print ("%f seconds taken in creating %u instances (GObject).\n",
               timer.elapsed (),
               NUM_INSTANCES);
    }

    public static int main (string[] args) {
        Test.Perf perf = new Test.Perf ();

        perf.test_struct ();
        perf.test_compact_class ();
        perf.test_class ();
        perf.test_mini_class ();
        perf.test_oclass ();

        return 0;
    }
}

