LoginSignup
15
4

More than 5 years have passed since last update.

[Python] Flask vs Fast API 速度を比較してみた

Last updated at Posted at 2019-04-23

Background

趣味で作成しているサービスのバックエンドの自作APIとしてFlaskを使用していました。
数日前、Qiitaを見ているとこんな記事がありました。

python製の最新APIフレームワーク FastAPI を触ってみた

とにかく早いらしいのですが、特に速度を比較した情報が見当たらなかったので作成しました。

環境

Windows 10

Python 3.6.7 :: Anaconda custom (64-bit)

インストール

Flask

pip install flask
pip install falsk_sqlalchemy

Fast API

pip install fastapi
pip install uvicorn

準備

DBと簡単なAPI、APIを叩くコードを書いていきます。

sqlite db

DBへの接続を試したいので、SQliteで試してみます。
基本的にはこちらを参考に作成
python3でsqlite3の操作。作成や読み出しなどの基礎。

TEST.db
[(1, 'Taro'), (2, 'Hanako'), (3, 'Hiroki')]

APIを叩くやつ

コメントアウトを入れ替えることでどちらにも対応しています。
FastAPIで通常のGETのように?hoge=fooとして引数を受け取る方式がよくわからなかったので、urlを少し変えています。
特になにもしないAPIと、IDを渡して、username(Hanako)を受け取るAPIを作成しようと思います。
100回APIを実行し、平均時間で速度を比べます。

call_api.py
import requests
import time

###Flask
URL = 'http://127.0.0.1:5000/'
#Fast API
#URL = 'http://127.0.0.1:8000/'

def main():
    t = []
    for i in range(100):
        start = time.time()
        #say_hello
        url = URL + 'hello'
        res = requests.get(url)
        print(res.text)
        #get_user
        url = URL + 'get_user?user_id=2' #flask
        #url = URL + 'get_user/2' #FastAPI
        res = requests.get(url)
        print(res.text)
        elapsed_time = time.time() - start
        t.append(elapsed_time)
    print(sum(t)/len(t))

if __name__=='__main__':
    main()

Flask、FaskApiともにSQLを書かずに済むSQLAlchemyを使用しています。

Flask

app.py
from flask import Flask, render_template, request, logging, Response, redirect, flash, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS

app = Flask(__name__)
CORS(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///./TEST.db'
db = SQLAlchemy(app)

class User(db.Model):
    __tablename__ = 'persons'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True)

    def __init__(self, username):
        self.username = username

@app.route('/hello', methods=['GET'])
def say_hello():
    print('hello flask')
    return 'hello'

@app.route('/get_user', methods=['GET'])
def get_user():
    user_id = request.args['user_id']
    username = User.query.get(user_id).name
    return username

if __name__ == '__main__':
    app.run()

FastAPI

こちらをコピペしつつ作成しました。

main.py
from fastapi import FastAPI
from sqlalchemy import Boolean, Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy.orm import Session, sessionmaker

app = FastAPI()

SQLALCHEMY_DATABASE_URI = 'sqlite:///./TEST.db'
engine = create_engine(
    SQLALCHEMY_DATABASE_URI, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

class CustomBase:
    # Generate __tablename__ automatically
    @declared_attr
    def __tablename__(cls):
        return cls.__name__.lower()

Base = declarative_base(cls=CustomBase)
Base.metadata.create_all(bind=engine)

db_session = SessionLocal()

class User(Base):
    __tablename__ = 'persons'
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, unique=True, index=True)

@app.get("/hello")
def say_hello():
    print('hello fastapi')
    return 'hello'

@app.get("/get_user/{user_id}")
def read_item(user_id: int):
    print(user_id)
    username = db_session.query(User).get(user_id).name
    return username

実行結果

1行目が何もしないAPI, 2行目がSQLを使うAPI, 3行目が実行時間の平均(秒)です。

Flask

hello
Hanako
0.03350924015045166

FastAPI

"hello"
"Hanako"
0.04411268472671509

Conclusion

Flaskの方が若干早いという結果でした。
そんなに公平にコーディングできた感はありませんし、大した処理もしていませんので、Flaskの方が早い!とはいえなさそうですが、
FastAPIの触れ込みの割には大して差はないとは言えるかもしれません。
このままFlaskを利用していこうかと思います。

15
4
1

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
15
4