Wydajność Pythona, C, C++ na przykładzie generowania miniatur grafik
4 August 2008
Comments
Parę dni temu bawiłem się różnymi bibliotekami do tworzenia miniatur z dużych plików JPG. EPEG to prosta biblioteka napisana w C, więc dość łatwo zrobić z niej moduł Pythona, a mając moduł Pythona można porównać różnice szybkości w działaniu czystego C od rozszerzenia C lub C++ dla języka skryptowego - Pythona :) Wspomniany test znajdziemy w Bibliotece CMS - Test tworzenia miniatur w PIL, Epeg i ImageMagick. Rozszerzenia w Pythonie możemy tworzyć w C używając API dostarczonego z Pythonem, lub też użyć biblioteki BOOST dla C++ posiadającą moduł umożliwiający proste tworzenie modułów Pythona.
Kod rozszerzeń C i C++/BOOST
Standardowe rozszerzenie Pythona napisane w C wyglądałoby tak:#include <stdlib.h>
#include <unistd.h>
#include <Python.h>
#include <Epeg.h>
static PyObject *
epg_thumbnail(PyObject *self, PyObject *args)
{
Epeg_Image * image;
int ch, height, quality, width;
char *input, *output;
if (!PyArg_ParseTuple(args, "ssiii", &input, &output, &quality, &height, &width))
return NULL;
image = epeg_file_open(input);
if (!image) {
exit (0);
}
epeg_decode_size_set(image, width, height);
epeg_quality_set (image, quality);
epeg_file_output_set(image, output);
epeg_encode(image);
epeg_close(image);
Py_BuildValue("i", 1);
}
static PyMethodDef epg_methods[] = {
{"thumbnail", (PyCFunction)epg_thumbnail, METH_VARARGS, "Funkcja epeg."},
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC initepg() {
Py_InitModule3("epg", epg_methods, "Miniatury z Epeg");
}
gcc -shared -I /usr/include/python2.5/ epg.c -o epg.so -fPIC `epeg-config --cflags --libs`
Rozszerzenie Pythona stworzone za pomocą BOOST wyglądałoby tak:
#include <boost/python.hpp>
#include <stdlib.h>
#include <unistd.h>
#include <Epeg.h>
int
thumbnail(char *input, char *output, int quality, int height, int width)
{
Epeg_Image * image;
int ch;
image = epeg_file_open(input);
if (!image) {
exit (0);
}
epeg_decode_size_set(image, width, height);
epeg_quality_set (image, quality);
epeg_file_output_set(image, output);
epeg_encode(image);
epeg_close(image);
return 0;
}
BOOST_PYTHON_MODULE(bstepg)
{
using namespace boost::python;
def("thumbnail", thumbnail);
}
gcc -lboost_python -shared -I /usr/include/python2.5/ bstepg.cpp -o bstepg.so -fPIC `epeg-config --cflags --libs` -I/usr/include/boost
Test szybkości działania
Dla 18 dużych plików JPG (tapety) o rozmiarze 35MB przeprowadziłem test tak jak opisany w Bibliotece CMS osiągając wyniki (użyłem inny zestaw plików):- EPEG - 4,15s
- PyEPEG C - 4,54s
- PyEPEG BOOST - 4,58s
- PIL - 11,61s
- IMAGEMAGICK - 29,32s
- IMAGEMAGICK -size - 10,9s (aktualizacja)

RkBlog
Comment article