0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Python実行速度をWindows / WSL2で測ってみたらかなり違った

0
Last updated at Posted at 2025-05-30

結論からいうと、
Python を動かすならWSL,
というかLinux

:dolphin: 目的

大学で先輩の研究を手伝うことになり、かなり時間のかかるPythonでのシミュレーションを実行する機会がありました。
そこで、「Linuxで動かしたほうが速いのでは?」と提案して試してみたところ、体感で明らかに速いと感じました。
本当に差があるのか、しっかり検証してみることにしました。

:wrench: 検証環境 & 手順

以下の環境で、同じコードを動かし検証します

Windows WSL2 (Ubuntu) Ubuntu24.04 LTS
OS Windows 11 Linux 6.6.87.1-microsoft-standard-WSL2 Linux 6.11.0-26-generic
OSバージョン 10.0.26100 #1 SMP PREEMPT_DYNAMIC Mon Apr 21 #26~24.04.1-Ubuntu SMP PREEMPT_DYNAMIC Thu Apr 17 19:20:47 UTC 2
アーキテクチャ AMD64 x86_64 x86_64
Python 3.13.3 3.12.3 3.12.3
プロセッサ Intel64 Family 6 Model 158 Stepping 9, GenuineIntel x86_64 x86_64

またハードウェアは
CPU: intel Core i5-7500
メモリ: DDR4 32GB
ディスク:SSDですが、WindowsはNVMe, UbuntuはSATAで分離しています

:whale2: 検証内容

3つの処理の時間を計測します。
(本当ならもっと"速度変化のある処理"があるはずですが、適当で簡単に気になるところだけを検証していきます。)

  1. シンプルな繰り返し処理
  2. モジュール(Numpy)を用いた複雑数値計算
  3. ファイルの入出力処理
検証コード
import os
import time
import platform
import numpy as np

print(f"OS: {platform.system()} {platform.release()}")
print(f"OSバージョン: {platform.version()}")
print(f"アーキテクチャ: {platform.machine()}")
print(f"Pythonバージョン: {platform.python_version()}")
print(f"プロセッサ: {platform.processor()}")

print()

# k回の平均を結果として出力する
k = 10
repetitions_result = [0] * k
numpydot_result = [0] * k
fileIO_result = [0] * k

for rep_i in range(k):
    print("1. for文の時間計測 - 0からnまで変化するiの2乗を計算")
    n = 1000000
    print(f"    繰り返し回数:n={n}")
    start = time.perf_counter()
    for i in range(n):
        if i % 2 == 0:
            _ = i * i
        else:
            _ = i * i * i
    end = time.perf_counter()
    print(f"    処理時間:{end - start:.6f}")
    repetitions_result[rep_i] = end - start

    print()
    print("2. Numpyによる行列計算 - n*nのランダムな行列を2つ生成し、行列の積を計算")
    n = 5000
    A = np.random.rand(n, n)
    B = np.random.rand(n, n)
    start = time.perf_counter()
    _ = np.dot(A, B)
    end = time.perf_counter()
    print(f"    処理時間:{end - start:.6f}")
    numpydot_result[rep_i] = end - start

    print()
    print("3. I/O処理の時間計測 - n回ファイルを読み書き")
    n = 10000
    print(f"    繰り返し回数:n={n}")
    start = time.perf_counter()
    os.makedirs("tests", exist_ok=True)
    for i in range(n):
        with open(f"tests/test{i}.txt", "w") as f:
            f.write(f"test{i}\n")
        with open(f"tests/test{i}.txt", "r") as f:
            _ = f.read()
    end = time.perf_counter()
    print(f"    処理時間:{end - start:.6f}")
    fileIO_result[rep_i] = end - start

print()
print("10回の平均:")
print(f"    for文の平均時間:{sum(repetitions_result) / k:.6f}")
print(f"    Numpyによる行列計算の平均時間:{sum(numpydot_result) / k:.6f}")
print(f"    I/O処理の平均時間:{sum(fileIO_result) / k:.6f}")

:bar_chart: 検証結果

ベンチ項目 (平均値) Windows WSL2 (Ubuntu) Ubuntu24.04 LTS
for ループ (1e6 回) 0.233145 s 0.220396 s 0.157500 s
NumPy 行列積 (5k×5k) 3.459947 s 2.918494 s 2.834514 s
ファイル I/O (1万回) 65.707492 s 1.661 s 0.664955 s

やはり、Linuxのほうが全体的に速いですね。

forループの繰り返し処理とNumpyの処理は概ね同じような時間ですが、
ファイルの読み書きが伴う処理に関してはWindowsが露骨に遅くなっています。

Pythonのバージョンによる差異があるかもしれませんが、おおむね3.13のほうが性能が向上しているらしいので、より顕著に表れているといえるでしょう。

:fishing_pole_and_fish: まとめ:WSL使え!

不思議ですよね。直感でいうとWSLはWindowsの仮想環境だからWindowsよりはせいぜい同じくらいだと思いますよね。
WSL1はWindows上のエミュレーション程度だったらしいのですが、WSL2ではHyper-Vなどの技術で完璧なサブマシンみたいな動作ができるようになったようです。
とはいうものの、GUI処理(tkinter等)がある場合WSLでは余計にめんどくっさいこともあるので、目的に応じてですね。

ただ処理速度ではWSLが断然いいとわかりました。
VSCodeを使ってるならリモートからWSLに接続もできるので、基本開発するときはWSLのほうがいいでしょうね。


:whale: メモ:なぜこんな差ができるのか?

  1. ファイルシステムの性能差
    WindowsはNTFS、Linuxはext4でディスクがマウントされています。
    NTFSはWindows特有すぎて、堅牢でセキュリティなどに強いですが速さを求めるI/O処理には適していないんですかね。

  2. :exclamation: (たぶん元凶)Windowsシステム関係ソフトが介入
    ファイルシステムだけでなく、Windows DefenderなどのWindowsシステムアプリが遅くすることもあるようです。
    ちいさなファイルが1つでもできるたびにDefenderがチェックしていくため、余計に遅くなるんでしょう。
    WSL2では仮想ディスク上のext4ファイルシステム(.vhdx)を使用しており、独立して動くそうです。
    むしろ、WSLで動かしてもWindowsのCドライブ上に保存するようだと効果がなく、遅くなるものだと思われます。

  3. I/Oシステムコールの軽さ
    Linuxはファイル操作(open / read / write / close など)のシステムコールが軽量に設計されています。
    Windowsでは内部的にAPI層が深く、仮想ファイルレイヤーやセキュリティの抽象層を何段階も通るため、オーバーヘッドが多くなります。

  4. I/Oキャッシュ
    WSL2では仮想的なLinuxカーネル上で処理が行われるため、Linux本来のファイルキャッシュ/書き込みバッファリング機構が効きます。

番外メモ:aptとpip

ubuntuにて、この検証のためPythonのnumpyを入れるときapt経由か、pip経由の2通りありました。
そもそも環境を立てたことないubuntuの環境だとpipすら入ってなかったので、apt経由で入れたところ、
Numpyによる行列計算の平均時間:87.665445秒
となり、非常に、異常に遅くなりました
windowsでも3秒くらいで処理できたのに、なぜ??

どうやら、apt経由では最小限の構成でしかインストールされず非常に遅くなる。というか高速化するためのライブラリが何も入らないため、かなり遅くなるらしいです。

pip経由だと、高速化するためのBLASモジュール(C拡張バイナリ)としてOpenBLASが組み込まれていて、これがSIMD(Single-Instruction, MultipleData)を使うようにビルドされており、より高速化されるそうです。


...というのも、pipがubuntuにプリインストールされてないし、仮想環境を作らずにpipを使おうとすると最近怒られるようになったのでaptで入れたんですけど、結局使い物になりませんでした。違いを知ることができてよかったです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?