Tuesday, April 12, 2011

pygir (pygir-ctypes) 0.1.0 VS pygtk 2.22.0 VS pygobject 2.26.0



For this benchmark, I use pygir-ctypes 0.1.0, pygtk 2.22.0, pygobject 2.26.0 libraries, and CPython 2.7.1, CPython 3.2 and PyPy 1.4.1 on ArchLinux x86_64. Benchmark shows startup time and memory consumption.

Startup times:
python2 python3 pypy
interpreter
(time PYTHON -c '')
0m0.099s 0m0.077s 0m0.072s
ctypes
(PYTHON -m timeit 'import ctypes')
0.885 usec 1.2 usec 1 usec
pygtk
(PYTHON -m timeit 'import pygtk; import gtk')
1.79 usec
pygobject
(PYTHON -m timeit 'import gi')
0.863 usec
pygir
(PYTHON -m timeit 'import gir')
1 usec 1.29 usec 1.1 usec
pygobject
(PYTHON -m timeit 'from gi.repository import Gtk')
2.02 usec
pygir
(PYTHON -m timeit 'from gir import Gtk')
92.6 usec 86.8 usec 500 usec
example1_pygtk.py
(PYTHON -m timeit -n 1 -r 10 'import example1_pygtk as ex; ex.main(True)')
895 usec
example1_pygobject.py
(PYTHON -m timeit -n 1 -r 10 'import example1_pygobject as ex; ex.main(True)')
1.15 msec
example1_pygir.py
(PYTHON -m timeit -n 1 -r 10 'import example1_pygir as ex; ex.main(True)')
2.38 msec 2.42 msec 38.9 msec

Memory consumption:
python2 python3 pypy
interpreter
(PYTHON)
3.9 MB 4.8 MB 8.6 MB
ctypes
(import ctypes)
4.1 MB 5.0 MB 8.8 MB
pygtk
(import pygtk; import gtk)
10 MB
pygobject
(import gi)
6.2 MB
pygir
(import gir)
7.5 MB 8.7 MB 12.8 MB
pygtk
(import pygtk; import gtk; cls = gtk.Window)
10 MB
pygobject
(from gi.repository import Gtk; cls = Gtk.Window)
7.4 MB
pygir
(from gir import Gtk; cls = Gtk.Window)
7.5 MB 8.9 MB 16.9 MB
example1_pygtk.py 10.6 MB
example1_pygobject.py 8.0 MB
example1_pygir.py 8.2 MB 10.7 MB 14.1 MB

Friday, August 6, 2010

Circular Dependency - An Interesting Solution

During development of Cosmos programming language, I faced to many usual and unusual problems related to C programming language. One of them was circular dependency which I like the most. Imagine file a.c includes a.h, b.c includes b.h, a.h includes b.h, and b.h includes a.h.

This is usually solved by using at least an extra H file storing some common parts of a.h and b.h. But, I really didn't want this so I solved it in following way. Have in mind that this is a trivial example:

main.c
#include "a.h"
#include "b.h"

int main(){
 a * v1;
 b * v2;
 return 0;
}

a.h
#ifndef CO_A_H
#define CO_A_H

struct a_t;

#include "b.h"

typedef struct a_t {
 struct b_t * value;
} a;

#endif

a.c
#include "a.h"

b * a_b(a * self){
 return 0;
}

b.h
#ifndef CO_B_H
#define CO_B_H

struct b_t;

#include "a.h"

typedef struct b_t {
 struct a_t * value;
} b;

#endif

b.c
#include "b.h"

a * b_a(b * self){
 return 0;
}

Saturday, June 26, 2010

Cosmos - Compiler and Virtual Machine

I have been thinking about Cosmos architectural design, and I realized that separating compiler and virtual machine in distinguishable shared/dynamic libraries is a great idea. Interpreter virtually encapsulates compiler and virtual machine. But in essence, it is just compiler and virtual machine. Compiler takes source code file/buffer and produces native code or bytecode. Virtual machine loads and runs native code or bytecode, and receives input and produces output.

Couple other things one should have in mind. Such a design means that other compiler and virtual machine implementations can be easily switched and tested without messy source code hackings.