Probelm mit embedding python (c / python)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Lufia
User
Beiträge: 83
Registriert: Samstag 13. Mai 2006, 10:04
Wohnort: Berlin

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)
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

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
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.
Lufia
User
Beiträge: 83
Registriert: Samstag 13. Mai 2006, 10:04
Wohnort: Berlin

@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.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

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
Lufia
User
Beiträge: 83
Registriert: Samstag 13. Mai 2006, 10:04
Wohnort: Berlin

@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.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

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
Antworten