AWS Lambdaのメモリ使用率と処理速度

AWS Lambdaのメモリ使用率と処理速度について調べてみました。

具体的には、以下についてLambdaを動かして試しました。

  • メモリ使用率が100%になるとエラーが起きたりするか?
  • メモリ使用率が高いと速度劣化するか?

まず、先に調査結果を書いちゃいます。以下の通りです。

調査結果

・メモリ使用率が100%になるとエラーが起きたりするか?
→エラーにはならない!
・メモリ使用率が高いと速度劣化するか?
→速度劣化する

では早速、調査していきます!

スポンサーリンク

メモリ使用率が100%になるとエラーが起きたりするか?について調査

調査方法

まず調査方法についてです。

以下の条件で調査しました。

前提条件

本記事では以下の条件で、調査しました。

言語:Python 3.12

Lambdaのタイムアウト設定:29

Lambdaのメモリ:128MB

調査で使用したソースコード

以下のソースを使用して調査しました。

import sys
import time
def lambda_handler(event, context):
    mem_test = []
    start = time.perf_counter()
    for i in range(5000000):
        mem_test.append(str(i))
        if i % 50000 == 0:
            print ('num:'+str(i))
            end = time.perf_counter()
            print(f"{end - start:.3f} s.")
            start = time.perf_counter()

ざっくり、以下のような処理のプログラムです。

  •  500万ループの中で、変数:mem_testに要素を追加
    • 要素を追加してメモリ使用量をあげる
    • 5万件おきにログ出力して、実行速度をログ出力

実行してみる

以下の実行結果になりました。

Task timed out after 29.55 seconds
Duration: 29548.53 ms Billed Duration: 29000 ms Memory Size: 128 MB Max Memory Used: 128 MB Init Duration: 79.60 ms

調査結果

処理がLambdaのタイムアウト時間以内に終わらずにエラーとなっていますが、メモリ全てを使ってもエラーにはならないことがわかりました。

以下の通り、ループを200万に減らして実行すると、タイムアウトせず、正常に処理終了しました。

<ソースコード>

import sys
import time
def lambda_handler(event, context):
    mem_test = []
    start = time.perf_counter()
    for i in range(2000000):
        mem_test.append(str(i))
        if i % 50000 == 0:
            print ('num:'+str(i))
            end = time.perf_counter()
            print(f"{end - start:.3f} s.")
            start = time.perf_counter()

<実行結果>

Duration: 9003.65 ms Billed Duration: 9004 ms Memory Size: 128 MB Max Memory Used: 128 MB Init Duration: 116.19 ms

 

次は、メモリ使用率が高いと速度劣化するか?についてみていきます。

メモリ使用率が高いと速度劣化するか?

上記の「メモリ使用率が100%になるとエラーが起きたりするか?」と同様の前提条件で、確認していきます。

調査①メモリ解放せずに500万ループする

以下のソースで確認していきます。

import sys
import time
def lambda_handler(event, context):
    mem_test = []
    start = time.perf_counter()
    for i in range(5000000):
        mem_test.append(str(i))
        if i % 50000 == 0:
            print ('num:'+str(i))
            end = time.perf_counter()
            print(f"{end - start:.3f} s.")
            start = time.perf_counter()

上記の「メモリ使用率が100%になるとエラーが起きたりするか?」と同様ですが、ざっくり、以下のような処理のプログラムです。

  •  500万ループの中で、変数:mem_testに要素を追加
    • 要素を追加してメモリ使用量をあげる
    • 5万件おきにログ出力して、実行速度をログ出力

調査①実行結果

途中でタイムアウトしたが、5万件毎の処理速度は0.220 s程度。メモリは限界まで(128MBまで)使っている。

Task timed out after 31.03 seconds
Duration: 31029.20 ms Billed Duration: 29000 ms Memory Size: 128 MB Max Memory Used: 128 MB Init Duration: 81.84 ms

調査②メモリ解放しつつに500万ループする

以下のソースコードで調査します。

調査①との違いは、最後の行で「mem_test = []」を使い、5万件毎に初期化をして、メモリ解放している点です。

import sys
import time
def lambda_handler(event, context):
    mem_test = []
    start = time.perf_counter()
    for i in range(5000000):
        mem_test.append(str(i))
        if i % 50000 == 0:
            print ('num:'+str(i))
            end = time.perf_counter()
            print(f"{end - start:.3f} s.")
            start = time.perf_counter()
            mem_test = []

調査②実行結果

途中でタイムアウトせず、5万件毎の処理速度は0.161s程度。メモリは36MBまで使っている。

Duration: 18596.18 ms Billed Duration: 18597 ms Memory Size: 128 MB Max Memory Used: 36 MB Init Duration: 83.56 ms

 

調査結果

適切にメモリ解放する方が、メモリ解放処理の時間を差し引いても早いことがわかりました。

まとめ

以下の結果となりました〜

調査結果まとめ

・メモリ使用率が100%になるとエラーが起きたりするか?
→エラーにはならない!
・メモリ使用率が高いと速度劣化するか?
→速度劣化する