Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung
Nächste Überarbeitung
Vorherige Überarbeitung
talit:python_advanced [2025-08-29 15:45] – [Numba] scatalit:python_advanced [2025-08-29 16:33] (aktuell) – [Numba] sca
Zeile 380: Zeile 380:
 ===== Numba ===== ===== Numba =====
  
-Numba ist ein Just-in-Time (JIT) Compiler für Python, der Funktionen mit Hilfe von LLVM in Maschinencode übersetzt. Besonders nützlich ist Numba für numerische Berechnungen mit NumPy, da es diese massiv beschleunigen kann – auch durch Parallelisierung.+Numba ist ein Just-in-Time (JIT) Compiler für Python, der Funktionen mit Hilfe von LLVM in Maschinencode übersetzt. Besonders nützlich ist Numba für **numerische Berechnungen mit NumPy**, da es diese **massiv beschleunigen** kann – auch durch **Parallelisierung**.
  
 Installation Installation
Zeile 387: Zeile 387:
 </code> </code>
  
-=== Beispiel ===+Tipps:
  
-Ursprünglicher Code ohne numba:+   * **Vermeide Python-Objekte** (z. B. Listen, Dictionaries). 
 +   * Nutze **NumPy-Arrays** und primitive Datentypen (z.B. int). 
 +   * Verwende `numba.set_num_threads(n)` zur Kontrolle der Thread-Anzahl. 
 + 
 + 
 +==== Beispiel: Prinzahlen ==== 
 + 
 +Wir schauen einen Code an, der ermittelt, wie viele Primzahlen es bis und mit einer vorgegebenen Zahl `n_max` gibt. Die Funktion `is_prime()` wurde dabei möglichst ineffizient programmiert. 
 + 
 +Version 1 ist der ursprüngliche Code, ganz ohne numba. In Version 2 wurde der Code mit ganz wenigen einfachen Anpassungen ungeschrieben und mit numba parallelisiert. Dabei konnte die Laufzeit von 26.5s auf 0.4s reduziert werden!!! 
 + 
 +**Version 1:** Ursprünglicher Code ohne numba. Zeit26.5s
 <code python> <code python>
 +n_max = 1e5
 +
 +def is_prime(x):
 +    for i in range(2,x):
 +        if x % i == 0:
 +            return False
 +    return True
 +
 +nr_primes = 0
 +for i in range(2,int(n_max)):
 +    if is_prime(i):
 +        nr_primes += 1
 +print(nr_primes)
 </code> </code>
  
-Erste Optimierung mit numba:+**Version 2:** Erste Optimierung mit numba. Zeit0.4s
 <code python> <code python>
 from numba import njit, prange from numba import njit, prange
 import numpy as np import numpy as np
 + 
 @njit @njit
 def is_prime(x): def is_prime(x):
Zeile 404: Zeile 428:
             return False             return False
     return True     return True
- +  
-@njit(parallel=True)+@njit(parallel=True, fastmath=True)
 def run(): def run():
     n_max = 3e4     n_max = 3e4
Zeile 413: Zeile 437:
             nr_primes += 1             nr_primes += 1
     return nr_primes     return nr_primes
 + 
 nr_primes = run() nr_primes = run()
 print(nr_primes) print(nr_primes)
 </code> </code>
 +
 +Bemerkungen:
 +
 +   * @njit(parallel=True) aktiviert die **Parallelisierung**.
 +   * `range` ersetzt durch `prange` (parallel-range): prange sorgt dafür, dass die Schleife über i *parallel* ausgeführt wird.
 +
 +==== Beispiel: Numpy-Arrays ====
 +
 +Hier ein einfaches Beispiel, welches Numpy-Arrays involviert:
 +
 +**Version 1**: ohne numba (8.0s)
 +<code python>
 +
 +import numpy as np
 +
 +def berechne_sinus(x_vals):
 +    result = np.empty_like(x_vals)
 +    for i in range(len(x_vals)):
 +        result[i] = np.sin(x_vals[i])
 +    return result
 +
 +x = np.linspace(0, 2 * np.pi, int(1e7))
 +y = berechne_sinus(x)
 +</code>
 +
 +**Version 2**: mit numba (0.2s)
 +<code python>
 +import numpy as np
 +from numba import njit, prange
 +
 +@njit(parallel=True, fastmath=True)
 +def berechne_sinus(x_vals):
 +    result = np.empty_like(x_vals)
 +    for i in prange(len(x_vals)):
 +        result[i] = np.sin(x_vals[i])
 +    return result
 +
 +x = np.linspace(0, 2 * np.pi, int(1e7))
 +y = berechne_sinus(x)
 +</code>
 +
  • talit/python_advanced.1756482302.txt.gz
  • Zuletzt geändert: 2025-08-29 15:45
  • von sca