DjangoとActix Webの性能を比べてみた

2021年11月10日

Django と Actix Web で簡単な性能比較をしてみました。

環境

マシン

  • MacOS 10.15.7
  • 1.2 GHz デュアルコアIntel Core m5
  • 8GB 1867 MHz LPDDR3

Actix Web

  • rustc 1.56.1 (59eed8a2a 2021-11-01)
  • release ビルドで cargo run

Django

  • Python 3.9.5 / Django 3.2.4
  • gunicornでリクエストを直受け(worker=3, worker_class=sync)
  • settings.py にて DEBUG=False

処理内容

  • hello world をレスポンス

ソースコード

Actix Web

use actix_web::{get, App, HttpResponse, HttpServer, Responder};

#[get("/")]
async fn hello() -> impl Responder {
    HttpResponse::Ok().body("hello world")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| App::new().service(hello))
        .bind("127.0.0.1:9002")?
        .run()
        .await
}

Django

# [views.py]
from django.http import HttpResponse
from django.views import View


class KenshoView(View):
    def get(self, request):
        return HttpResponse('hello world')

# [urls.py]
from django.urls import path
from app.views import KenshoView

urlpatterns = [
    path('', KenshoView.as_view()),
]

リクエスト

具体的なリクエストレスポンスは以下となります。 Django は初期状態で色んな middleware が有効化されているので、前提条件的には不利かも。

Actix Web

$ curl -v http://127.0.0.1:9002/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 9002 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:9002
> User-Agent: curl/7.64.1
> Accept: */*
> 
< HTTP/1.1 200 OK
< content-length: 11
< date: Wed, 10 Nov 2021 04:10:59 GMT
< 
* Connection #0 to host 127.0.0.1 left intact
hello world
* Closing connection 0

Django

$ curl -v http://127.0.0.1:9003/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 9003 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:9003
> User-Agent: curl/7.64.1
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: gunicorn
< Date: Wed, 10 Nov 2021 04:10:05 GMT
< Connection: close
< Content-Type: text/html; charset=utf-8
< X-Frame-Options: DENY
< Content-Length: 11
< X-Content-Type-Options: nosniff
< Referrer-Policy: same-origin
< 
* Closing connection 0
hello world

計測してみる

abコマンドを使って測定しました。マシンスペックが低すぎて限界性能を測定するのは叶わず。いずれの結果もエラー率は0%で正常に応答を返しています。同時接続数は 100 が限界でした。

Requests per sec

おおよそ10倍の差が出ました。

条件Actix WebDjango
n=1000, c=1010412.221145.46
n=2000, c=5010761.481182.24
n=3000, c=10010853.561170.74

平均レスポンスタイム(ms)

こちらも10倍程度 Actix Web が勝ちです。

条件Actix WebDjango
n=1000, c=100.8568.165
n=2000, c=504.76445.183
n=3000, c=1009.04886.184

最大レスポンスタイム(ms)

条件Actix WebDjango
n=1000, c=10214
n=2000, c=501076
n=3000, c=10020196

所感

hello world のレスポンステストなので実用面で考えたときの指標としては使えないですが、Rust の可能性を感じさせる結果となりました。 コンパイル言語のRustは速いですね。次は DB fetch ありのロジックでテストしてみたいと思います。


Web系エンジニアでPython好き。バックエンド/フロントエンド問わずマルチな方面でエンジニアリングしています。