PythonでJITを使うと高速化可能だと聞いて試し。∑(1/n)を n= 1 から 10億まで計算
import time
from numba import jit
@jit # ここね、ここでじっとしとれやあァァァ なにを!
def series_sum(num_max):
sum = 0
for n in range(1, num_max + 1):
sum += 1 / n
return sum
print("** Start **")
print("dummy ", series_sum(10)) # JITコンパイラをここで働かせる
time_start = time.perf_counter() # これが精度高いらしい
# num_max = 100_000_000
# 1億
num_max = 1_000_000_000 # 10億
sum_b = series_sum(num_max) # JITコンパイル済みでして
print("1から", num_max, "まで :", sum_b, "\n") # 収束しない
time_end = time.perf_counter()
time = time_end - time_start
print("経過時間 : ", time)
結果は10億で 約4秒。これはすばらしい・・・気がする。C++でも4秒ぐらいだったのでしてね。そりゃJITコンパイラがコンパイルするのだからC++に匹敵するだろなあ。ってかね。
実は高速化のためにはdummyが必要なのである。上のdummyのところでJITがコンパイルする。よってに2回めのseries_sum(num_max)ではコンパイラ済みのコードが働くのである。これをしないと高速化になりませぬぞま。
こういうの初回にJITが働くので初回は遅くなるってのが一般的な話だすぞの。。かも。
上の試したときに、高速化しないぞ、ゴラァとワタクシはCopilot先生やchatGPT3.5先生に訊いたのである。初回は遅くなるというので、だったらダミー入れたれやと思った次第である。
C++では最適化してないでの4秒ぐらいだった。後で最適化かましたら少しは改善するか試そうっと。
PythonはNumpyとかJITとかで高速化できるのであーーーた。そんだけ。
ちなみに∑(1/n)は収束しない。limit(1/n) = 0, n –>無限大 なので無限大で0になるのだったら足しても増えないはずだから収束するはず・・・・と考えたワタクシである。しかし、収束しない。どうしてかというと limit(1/n) = 0 とはならないからだ。ここの[ = ] は0と等しいという意味ではなくて数学屋の屁理屈で極限を意味するのであーーーーた。
ほんで昔の数学屋で超・賢いオイラーだかゼーマンだかが近似式も出しているのである。
∑(1/n) ≒ ln(n) + γ である。ln(n)は自然対数である。自然対数のグラフを思い浮かべよ。nを非常に大きくしても ln(n) は ゆるやかに 増える。
上の計算は10億までで 21.3ぐらい。DELL OPTIPLEX 7010SFF Win 11 23H2(非推奨PC)で4秒。
100億だと単純に10倍で 40秒。1000億だと単純に400秒。1兆だと4000秒で1時間を軽く越えてしまいますわ。10兆まで計算すると・・・100兆まで計算すると・・・
DELL OPTIPLEX 7010SFF Win 11 23H2(非推奨PC)の貧弱なCPUでは どもならんほーるど。
しかし、C++ではOpenMPという並行処理・並列処理のツールが使えて。それ使うと速くなることは速くなる。しかーーーし、もうやらん。
自分で確認したのは∑(1/n) ≒ ln(n) + γ で10兆までだな。。。。
とにかく収束しないという事はわかったのである。10兆まで微妙に微妙に増えるのでした。
数学ってフシギあるね。ワタシ にがて あるのよさ。
ちなみにC++での計算では int n ではだめなのだよよよん。扱える数値を考えませう。
いじょ PythonでJIT使うと高速化可能でC++に匹敵するという話でした。
蛇足 つまり蛇の足 Python高速化でJITコンパイラ使うって場合には上の numba だけではないみたい。
Numba, PyPy, Cython, などあるようだ。そのうち試そう。どうせチャッターズの回答をコピペしてVScodeでクリックするだけだ
posted by toinohni at 08:11| 東京 ☁|
Comment(0)
|
ソフト系雑学
|
|