2016-05-01 6 views
4

Ich habe pi aproximation Code sehr ähnlich, die auf der offiziellen Seite:Julia pi aproximation langsam

function piaprox() 
    sum = 1.0 
    for i = 2:m-1 
     sum = sum + (1.0/(i*i)) 
    end 
end 

m = parse(Int,ARGS[1]) 
opak = parse(Int,ARGS[2]) 

@time for i = 0:opak 
    piaprox() 
end 

Wenn ich versuche, Zeit von C und Julia zu vergleichen, dann Julia ist deutlich langsamer, fast 38 sec für m = 100000000 (Zeit von C ist 0,1608328933 Sekunden). Warum passiert das?

Antwort

14
julia> m=100000000 
julia> function piaprox() 
      sum = 1.0 
      for i = 2:m-1 
       sum = sum + (1.0/(i*i)) 
      end 
     end 
piaprox (generic function with 1 method) 

julia> @time piaprox() 
28.482094 seconds (600.00 M allocations: 10.431 GB, 3.28% gc time) 

Ich möchte von Performance Tips Abschnitt von julia Dokumentation zwei sehr wichtige Absätze erwähnen:

Avoid global variables Eine globale Variable ihren Wert haben könnte, und daher seine Art, Änderung an irgendeiner Stelle. Dies macht es für den Compiler schwierig, Code mit globalen Variablen zu optimieren. Variablen sollten sein, lokale oder als Argumente an Funktionen übergeben, wann immer dies möglich .....

Das Makro @code_warntype (oder dessen Funktionsvariante code_warntype()) kann manchmal hilfreich sein, typbezogene Probleme bei der Diagnose.

julia> @code_warntype piaprox(); 
Variables: 
    sum::Any 
    #s1::Any 
    i::Any 

Es ist klar, aus @code_warntype Ausgang, den Compiler nicht Arten von lokalen Variablen in piaprox() erkennen kann. Also versuchen wir Arten zu erklären und entfernen globale Variablen:

function piaprox(m::Int) 
    sum::Float64 = 1.0 
    i::Int = 0 
    for i = 2:m-1 
     sum = sum + (1.0/(i*i)) 
    end 
end 
julia> @time piaprox(100000000) 
    0.009023 seconds (11.10 k allocations: 399.769 KB) 
julia> @code_warntype piaprox(100000000); 
Variables: 
    m::Int64 
    sum::Float64 
    i::Int64 
    #s1::Int64 

EDIT

als @ user3662120 kommentiert, das superschnelle Verhalten der Antwort ist Folge eines Fehlers, ohne Rückgabewert LLVM könnte ignorieren die for-Schleife, durch das Hinzufügen einer Rücklaufleitung der @time Ergebnis wäre:

julia> @time piaprox(100000000) 
    0.746795 seconds (11.11 k allocations: 400.294 KB, 0.45% gc time) 
1.644934057834575 
+4

Beachten Sie, dass die Typenannotationen auf 'm' und' sum' für Geschwindigkeit nicht notwendig sind. – StefanKarpinski

+2

Die Typ-Annotationen (:: Int, :: Float64) tragen hier eigentlich nichts zur Performance bei. (Das Hinzufügen von unnützen Typanmerkungen ist ein gewöhnlicher Julia-Fehler.) Beachten Sie auch, dass Sie vergessen, die Summe zurückzugeben. (LLVM könnte tatsächlich die ganze Schleife optimieren!) – SGJ