Seite 1 von 1

Probelm mit embedding python (c / python)

Verfasst: Montag 17. September 2007, 13:18
von Lufia
Hallo,

beim embedding von Python tritt bei mir das Problem, das die Aufrufe des Python Programms mit der Zeit immer langsamer werden. Ich bin mir nicht sicher woran genau es liegt. Evtl. hat hier im Forum jemand mehr Erfahrung als ich und etdeckt den Fehler sofort, ich bin etwas ratlos. Ich habe anbei etwas Beispielcode angehängt. Meine eigentliche Anwednung ist komplexer, das Prfoblem tritt hier aber auch auf.

Danke schon mal für jede Hilfe,

Lufia


Code: Alles auswählen

#include <Python.h>
#include <time.h>

int test()
{
    PyObject *pName, *pModule, *pFunc;
    PyObject *pArgs, *pValue;
    int i,test; 
    double array[2];

    array[0] = 4.2341234;
    array[1] = 3.3;
    
    // Initialisierung
    Py_Initialize();
    
    // damit python im richtigen verzecihniss sucht
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.insert(0, '')");
    
    /* Programm / Modul Laden */
    pName = PyString_FromString("multi");
    
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);

    /* Funktion laden und ausfuehren */
    if (pModule != NULL) {
        pFunc = PyObject_GetAttrString(pModule,"multi");
        
        
        /* falls ausfuehrbar Programm starten */
        if (pFunc && PyCallable_Check(pFunc)) {
            
            /* Tuple mit 2 eintraegen fuer uebergabe nach Pyhton erstellen*/ 
            pArgs = PyTuple_New(2);
            
            /* Entraege abspeichern */
            for (i = 0; i <2 ; ++i) {
                pValue = PyFloat_FromDouble(array[i]);
                if (!pValue) {
                    Py_DECREF(pArgs);
                    Py_DECREF(pModule);
                    fprintf(stderr, "Cannot convert argument\n");
                    return 1;
                }
                /* Variable im tuple pArgs abspeichern: */
                PyTuple_SetItem(pArgs, i, pValue);
            }

            /*Funktion aufrufen */
            pValue = PyObject_CallObject(pFunc, pArgs);

        
            Py_DECREF(pArgs);
            if (pValue != NULL) {
                /*printf("Result of call: %f \n", PyFloat_AsDouble(pValue));*/
                Py_DECREF(pValue);
            }
            else {
                Py_DECREF(pFunc);
                Py_DECREF(pModule);
                PyErr_Print();
                fprintf(stderr,"Call failed\n");
                return 1;
            }
        }
        else {
            if (PyErr_Occurred())
                PyErr_Print();
            fprintf(stderr, "Cannot find function \n");
        }
        Py_XDECREF(pFunc);
        Py_DECREF(pModule);
    }
    else {
        PyErr_Print();
        fprintf(stderr, "Failed to load ");
        return 1;
    }
    Py_Finalize();
    return 0;
}


int main(void){
    int i,j,value;
    time_t begin,end;
    double timediff;

    for(i=0;i<=20000;i++)
    {
        time(&begin);
        for(j=0;j<=200;j++){
            value = test();
        }     
        time(&end);
        timediff = difftime(end,begin);
        printf ("\n Zeit in Sekunden war %f",timediff);
      
    }
    return 0;
    
}
Das Pyhton Programm sieht wie folgt aus:

Code: Alles auswählen

def multi(a,b):
    #print "Will compute", a, "times", b
    c = 0
    c = a * b
    return c
Das verwendete Makefile dazu ist:

Code: Alles auswählen

COMPILER = gcc 
LINKER   = gcc 
CFLAGS   = -c 
LFLAGS   = -lpython2.4 -lm -L/usr/lib/python2.4/config
INCLUDE  = -I/usr/include/python2.4

COMMAND = wurst
SOURCES = main.c 

OBJFILES = $(SOURCES:.c=.o)

# --------

# mach aus dem c ein o
.c.o: $(SOURCES)
	$(COMPILER) $(CFLAGS) $(INCLUDE) -o $@ $< 

# linke die o zu einem programm
all: $(OBJFILES)
	$(LINKER) $(LFLAGS) $(OBJFILES) -o $(COMMAND) 

# mach sauber
clean:
	rm $(OBJFILES)

# mach richtig sauber
distclean: clean
	rm $(COMMAND)

Verfasst: Montag 17. September 2007, 13:48
von CM
Hoi,

vorweg: in der "multi"-Funktion reicht auch

Code: Alles auswählen

return a*b
.

Zum eigentlichen Problem: Hilft es wenn Du die Zeilen 7, 8, 16, 19 und20 in main() verschiebst?

Gruß,
Christian

Verfasst: Montag 17. September 2007, 13:56
von lunar
Bei so langen Listings wäre es sinnvoller, einen Nopaste-Service (z.B. http://paste.pocoo.org) zu verwenden, zu mal man dann auch Syntax-Highlighting hätte.

Verfasst: Montag 17. September 2007, 14:43
von Lufia
@lunar:
Danke, ich kenne mich da noch nicht so gut aus, ich werde es das nächste mal so machen.

@CM:
Das war ein super wink! Es reicht scheinbar wenn Py_Initialize(); und Py_Finalize(); in der main funktion stehen. Vieln lieben Dank, ich werde es noch kurz in meiner großen Applikation testen.

Warum das so sein muss ist mir noch nicht ganz klar.

Verfasst: Montag 17. September 2007, 16:14
von CM
Lufia hat geschrieben: Warum das so sein muss ist mir noch nicht ganz klar.
Aber mir: http://docs.python.org/api/initialization.html

Dafür hatte ich das Py_Finalize() übersehen und in der Tat eigentlich muß es reichen Initialize und Finalize in main() zu schreiben ...

Gruß,
Christian

Verfasst: Montag 17. September 2007, 17:01
von Lufia
@CM vielen lieben Dank, da habe ich wieder etwas gelernt!

In meiner größeren Applikation funktioniert es jetzt auch bestens. Wie dumm von mir,... :roll: ich hatte mich an ein paar einfachen Beispielen zu weit hochgearbeitet ohne alle Basics verstanden zu haben.
Leider gibt es nicht allzu viele Anleitungen (vor allem deutschsprachig) zu dem Thema. Es scheint ob wird es nicht so oft genutzt, oder ist den vorhanden Nutzern eh schon klar.

Verfasst: Dienstag 18. September 2007, 10:01
von CM
Lufia hat geschrieben: In meiner größeren Applikation funktioniert es jetzt auch bestens. Wie dumm von mir,... :roll: ich hatte mich an ein paar einfachen Beispielen zu weit hochgearbeitet ohne alle Basics verstanden zu haben.
Ach was, man muß halt erst mal anfangen und Du hast schon recht: Die Doku ist da reichlich kryptisch.
Lufia hat geschrieben: Leider gibt es nicht allzu viele Anleitungen (vor allem deutschsprachig) zu dem Thema. Es scheint ob wird es nicht so oft genutzt, oder ist den vorhanden Nutzern eh schon klar.
Finde ich eigentlich auch und es hat mich schon eine ganze Weile gestört: Deshalb habe ich hier im Forum mal eine Linksammlung zum Thema Extending angefangen. Vielleicht magst Du etwas Vergleichbares zum Thema Embedding machen?

Gruß,
Christian