Frage

Ich erstelle in Python (3.3.1) ein Modell für einen recht einfachen, aber umständlichen Vertrag mit langfristigen Cashflows.Das komplette Modell ist im Hinblick auf den Zeitaufwand ziemlich komplex und deshalb habe ich beschlossen, es zu profilieren.Allerdings bekomme ich mit und ohne Profiling unterschiedliche Antworten.

Ich habe den Code auf folgendes Beispiel reduziert:

def generate_cashflows( income ):
    contingent_expense = [1000.0]
    income_cf = [income]
    outgo_cf = [ -0.001 * contingent_expense[0] ]
    bank = [ income_cf[0] + outgo_cf[0] ]

    for t in range(1, 20):
        contingent_expense.append(1000.0)
        income_cf.append( income )
        outgo_cf.append( -contingent_expense[t] * 0.001 )
        bank.append(    bank[t-1] * (1+0.05)**(1/12)
                + income_cf[t]
                + outgo_cf[t]
                )
    return bank[-1]

print(str(generate_cashflows(0)))

Ausgabe:

calum@calum:~/pricing/model$ ./scratch.py 
-20.793337746348953
calum@calum:~/pricing/model$ python -m cProfile scratch.py
-20.0
     80 function calls in 0.000 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    0.000    0.000 scratch.py:5(<module>)
    1    0.000    0.000    0.000    0.000 scratch.py:5(generate_cashflows)
   76    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
    1    0.000    0.000    0.000    0.000 {range}


calum@calum:~/pricing/model$ 

Gibt es eine einfache Erklärung dafür, warum jedes Mal eine andere Antwort ausgegeben wird?Ich habe das Handbuch gelesen, aber ich sehe nichts Offensichtliches.

War es hilfreich?

Lösung

Zuerst habe ich versucht, mit Python3 zu reproduzieren, und beim Ausführen von „python3 scratch.py“ und „python3 -m cProfile scratch.py“ wird jeweils -20,7933 ausgegeben ...auf meiner Maschine.

Der Grund, warum -20.0 in Python 2.x zurückgegeben wird, liegt darin, dass der Divisionsoperator „/“ in Python2.x anders funktionierte (http://legacy.python.org/dev/peps/pep-0238/)

In Python2 ist 1/12 == 0

In Python3 ist 1/12 == 0,08333333 ....

Das bedeutet, dass in Python2 die Zeile

 bank.append(    bank[t-1] * (1+0.05)**(1/12)

vereinfacht zu

 bank.append(    bank[t-1] * (1+0.05)**(0)

oder

 bank.append(    bank[t-1] * 1

Das ist wahrscheinlich nicht das, was Sie beabsichtigt haben.Die Python3-Interpretation ist wahrscheinlich korrekt und die Python2-Interpretation ist ziemlich nutzlos.Als Randbemerkung: Die Änderung von (1/12) in (1.0/12) führt zu einer identischen Ausgabe auf Python2 und Python3 und führt dazu, dass Ihr Code mit oder ohne Profilerstellung dieselbe Ausgabe zurückgibt, aber das behandelt das Symptom und nicht die Ursache .

Meine beste Vermutung, warum Sie die unterschiedlichen Ausgaben mit und ohne Profilerstellung erhalten, ist, dass Sie Python3 ohne Profilerstellung und Python2 mit Profilerstellung verwenden.Um aussagekräftige Ergebnisse zu erhalten, ist es wichtig, beim Ausführen Ihres Codes mit und ohne Profilerstellung dieselbe Python-Version zu verwenden.

Die Tatsache, dass Sie ./scratch.py ​​verwenden, weist darauf hin, dass Sie wahrscheinlich eine Zeile wie

#!/usr/bin/python3

oben in scratch.py ​​(obwohl es nicht im bereitgestellten Code enthalten ist).Wenn du rennst

./scratch.py

/usr/bin/python3 wird zum Ausführen der Datei verwendet

Wenn du rennst

python -m cProfile scratch.py

Ihr Standard-Python-Interpreter wird zum Ausführen der Datei verwendet (ich vermute, dass es sich um Python2 handelt).

Wenn Sie „python“ über die Befehlszeile ausführen (ohne weitere Argumente), werden Sie wahrscheinlich feststellen, dass der Standardinterpreter 2.X ist.

Daher sollte es so einfach sein, Ihren Code dazu zu bringen, mit und ohne Profilierung eine identische Ausgabe zurückzugeben, indem Sie bei der Profilierung einfach python3 angeben:

 python3 -m cProfile scratch.py
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top