はじめに
Javaはコールドスタート時の実行速度が遅いと言うのはよく見聞きしていましたが実際に計測したことはなかったのでやってみました。
環境
計測に使うサンプルプログラムを作成するのにAWS SAMを使用しています。
- Windows 10 Pro
- AWS CLI:2.6.2
- AWS SAM CLI:1.105.0
準備
計測は次の言語で行いました。
言語 | ランタイム | メモリ | コードサイズ | リージョン |
---|---|---|---|---|
Go | provided.al2023 | 128MB | 4.6 MB | ap-northeast-1 |
Java | java21 | 128MB | 854.6 KB | ap-northeast-1 |
JavaScript | nodejs20.x | 128MB | 1.3 KB | ap-northeast-1 |
Python | python3.10 | 128MB | 521.1 KB | ap-northeast-1 |
計測に使用するサンプルプログラムをAWS SAMで作成します。
以下はJava21のランタイムを選択した場合の例になります。他のランタイムも若干選択肢は異なりますが基本的には同じものを選択するようにしています。
$ sam init
You can preselect a particular runtime or package type when using the `sam init` experience.
Call `sam init --help` to learn more.
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1
Choose an AWS Quick Start application template
1 - Hello World Example
2 - Data processing
3 - Hello World Example with Powertools for AWS Lambda
4 - Multi-step workflow
5 - Scheduled task
6 - Standalone function
7 - Serverless API
8 - Infrastructure event management
9 - Lambda Response Streaming
10 - Serverless Connector Hello World Example
11 - Multi-step workflow with Connectors
12 - GraphQLApi Hello World Example
13 - Full Stack
14 - Lambda EFS example
15 - Hello World Example With Powertools for AWS Lambda
16 - DynamoDB Example
17 - Machine Learning
Template: 1
Use the most popular runtime and package type? (Python and zip) [y/N]:
Which runtime would you like to use?
1 - aot.dotnet7 (provided.al2)
2 - dotnet6
3 - go1.x
4 - go (provided.al2)
5 - go (provided.al2023)
6 - graalvm.java11 (provided.al2)
7 - graalvm.java17 (provided.al2)
8 - java21
9 - java17
10 - java11
11 - java8.al2
12 - java8
13 - nodejs20.x
14 - nodejs18.x
15 - nodejs16.x
16 - python3.9
17 - python3.8
18 - python3.12
19 - python3.11
20 - python3.10
21 - ruby3.2
22 - ruby2.7
23 - rust (provided.al2)
24 - rust (provided.al2023)
Runtime: 8
What package type would you like to use?
1 - Zip
2 - Image
Package type: 1
Which dependency manager would you like to use?
1 - gradle
2 - maven
Dependency manager: 1
Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]: y
X-Ray will incur an additional cost. View https://aws.amazon.com/xray/pricing/ for more details
Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]:
Would you like to set Structured Logging in JSON format on your Lambda functions? [y/N]:
Project name [sam-app]: Java
-----------------------
Generating application:
-----------------------
Name: Java
Runtime: java21
Architectures: x86_64
Dependency Manager: gradle
Application Template: hello-world
Output Directory: .
Configuration file: Java\samconfig.toml
Next steps can be found in the README file at Java\README.md
Commands you can use next
=========================
[*] Create pipeline: cd Java && sam pipeline init --bootstrap
[*] Validate SAM template: cd Java && sam validate
[*] Test Function in the Cloud: cd Java && sam sync --stack-name {stack-name} --watch
次のようなAPIGateway+Lambda構成のSAMテンプレートが作成されます。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
Java
Sample SAM Template for Java2
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 20
MemorySize: 512
Tracing: Active
Api:
TracingEnabled: true
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: HelloWorldFunction
Handler: helloworld.App::handleRequest
Runtime: java21
Architectures:
- x86_64
MemorySize: 512
Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
Variables:
PARAM1: VALUE
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /hello
Method: get
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
HelloWorldApi:
Description: API Gateway endpoint URL for Prod stage for Hello World function
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
HelloWorldFunction:
Description: Hello World Lambda Function ARN
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: Implicit IAM Role created for Hello World function
Value: !GetAtt HelloWorldFunctionRole.Arn
このままデプロイしても問題ありませんが、APIGatewayは不要なためコメントアウトすることにしました。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
Java
Sample SAM Template for Java
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 20
MemorySize: 512
Tracing: Active
Api:
TracingEnabled: true
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: HelloWorldFunction
Handler: helloworld.App::handleRequest
Runtime: java21
Architectures:
- x86_64
MemorySize: 512
Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
Variables:
PARAM1: VALUE
# Events:
# HelloWorld:
# Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
# Properties:
# Path: /hello
# Method: get
# Outputs:
# # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# # Find out more about other implicit resources you can reference within SAM
# # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
# HelloWorldApi:
# Description: API Gateway endpoint URL for Prod stage for Hello World function
# Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
# HelloWorldFunction:
# Description: Hello World Lambda Function ARN
# Value: !GetAtt HelloWorldFunction.Arn
# HelloWorldFunctionIamRole:
# Description: Implicit IAM Role created for Hello World function
# Value: !GetAtt HelloWorldFunctionRole.Arn
また、MemorySizeは比較の条件を合わせるため128MBを指定するように変更します。
選択するランタイムによってはSAMテンプレートにMemorySizeの指定がされていない場合があるため追記が必要です。
Globals:
Function:
Timeout: 20
MemorySize: 128 # ここを追加・変更
計測結果
計測の方法はこちらの記事を参考にさせていただきました。
各言語のLambdaを100回実行した平均になっています。
Lang | Cold Start or Warm Start | total(ms) | initialization(ms) | invocation(ms) | overhead(ms) |
---|---|---|---|---|---|
Go | warm | 10.13 | - | 0.61 | 0.33 |
Java | warm | 226.54 | - | 218.44 | 0.92 |
JavaScript | warm | 10.63 | - | 1.12 | 0.51 |
Python | warm | 7.99 | - | 0.76 | 0.18 |
Go | cold | 273.99 | 57.39 | 0.91 | 0.95 |
Java | cold | 11448.99 | 591.27 | 10676.08 | 20.06 |
JavaScript | cold | 292.99 | 132.11 | 14.15 | 58.87 |
Python | cold | 256 | 109.34 | 0.67 | 0.12 |
Javaはwarmスタートでもかなり遅い結果となっています。
AWS SAMで作成したサンプルプログラムが外部URLを参照する作りになっていることやメモリサイズが128MBとそもそも少なすぎる設定にしてしまった影響を受けているのかもしれません。
それ以外の言語ではあまり大きな差は見られなかったと言っても良さそうです。
前述の参考にした記事の時点から言語のバージョンも上がっているためパフォーマンス向上に期待をしていましたが誤差程度の差しかなかったと言えそうです。
おわりに
見聞きしていた通りの結果でしたが、自分で試してみる貴重な経験になりました。
選定の参考になりましたら幸いです。
最近であればJavaのスナップスタートやRustの実行速度も気になっているため、次の機会にこのあたりも触ってみたいと思います。