Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
3cbc3b0
Implement Pypy local & aws container deployments
toooadi Dec 1, 2025
c5bf19d
Upgrade to Amazon Linux 2023
toooadi Dec 1, 2025
5bf464c
pypy azure
xSurus Dec 7, 2025
9db20b9
Update config/systems.json
toooadi Dec 8, 2025
cdd9998
added pypy support for other benchmarks
xSurus Dec 10, 2025
274856d
Add Java runtime support for AWS Lambda and Azure Functions
xSurus Dec 11, 2025
dbf648d
rust support for aws
xSurus Dec 12, 2025
892cd38
gitignore fix
xSurus Dec 12, 2025
47f6a8f
Adapt pypy installer
toooadi Dec 12, 2025
f51c7c4
Merge branch 'feat/java-runtime' into feat/merged-benchmarks
xSurus Dec 12, 2025
ccc9b8d
Merge branch 'features/pypy-runtime-azure' into feat/merged-benchmarks
xSurus Dec 12, 2025
ea2dfb9
benchmark merge
xSurus Dec 12, 2025
0788ab3
more merge changes
xSurus Dec 12, 2025
f4470c2
Adapt system.json
toooadi Dec 12, 2025
7676d29
Merge branch 'features/pypy-runtime' of https://github.com/toooadi/se…
toooadi Dec 12, 2025
c98b7b7
Add GCP container support
toooadi Dec 12, 2025
421d8ff
Add GCP Pypy container benchmark files
toooadi Dec 12, 2025
686719b
fix gcp images to specific runtime versions instead of ubuntu
markbeep Dec 13, 2025
46ad66d
Merge pull request #2 from markbeep/fix-gcp-base-images
toooadi Dec 13, 2025
8e4a8be
Adapt AWS deployments
toooadi Dec 13, 2025
e783b8f
Add systems.json for aws
toooadi Dec 13, 2025
d43af67
GCP add arm64 support (containers)
toooadi Dec 14, 2025
9402163
Add support for non-wheel images
toooadi Dec 14, 2025
596d440
Add further non-wheel dependencies
toooadi Dec 14, 2025
e7095ff
Add more benchmarks
toooadi Dec 14, 2025
5047479
added script for running benchmarks on multiple languages
xSurus Dec 15, 2025
ed1afb1
Merge branch 'features/pypy-runtime' into feat/merged-benchmarks
xSurus Dec 15, 2025
e2657d3
force aws pypy to --container-deployment
xSurus Dec 15, 2025
acfc7c9
Add benchmarking scripts and configuration
xSurus Dec 16, 2025
2c87f46
Add plot_comparison.py script
xSurus Dec 16, 2025
a6543d6
Add architecture and container-deployment options
toooadi Dec 16, 2025
5b2da48
Merge branch 'benchmarking-tools' into feat/merged-benchmarks
xSurus Dec 18, 2025
d55e8b4
Feature: Multi-language Support (Rust, PyPy, Java) & Enhanced Benchma…
xSurus Jan 8, 2026
2d36148
Remove plotting and benchmarking scripts
xSurus Jan 8, 2026
e99192e
Update build and deployment configurations
xSurus Jan 8, 2026
c4b559f
Refactor build configurations and enhance Java support
xSurus Jan 8, 2026
e299a32
PR code review changes.
xSurus Jan 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,5 @@ cache
*.iml

# MacOS Finder
**/.DS_Store
**/.DS_Store
results/*
2 changes: 1 addition & 1 deletion benchmarks/000.microbenchmarks/010.sleep/config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"timeout": 120,
"memory": 128,
"languages": ["python", "nodejs"],
"languages": ["python", "nodejs", "java", "rust", "pypy"],
"modules": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package function;

import java.util.HashMap;
import java.util.Map;

public class Function {

public Map<String, Object> handler(Map<String, Object> event) {
double sleepSeconds = parseSeconds(event.get("sleep"));
try {
Thread.sleep((long) (sleepSeconds * 1000));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
Map<String, Object> result = new HashMap<>();
result.put("result", sleepSeconds);
return result;
}

private double parseSeconds(Object value) {
if (value instanceof Number) {
return ((Number) value).doubleValue();
}
if (value instanceof String) {
try {
return Double.parseDouble((String) value);
} catch (NumberFormatException ignored) {
return 0;
}
}
return 0;
}
}
9 changes: 9 additions & 0 deletions benchmarks/000.microbenchmarks/010.sleep/pypy/function.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

from time import sleep

def handler(event):

# start timing
sleep_time = event.get('sleep')
sleep(sleep_time)
return { 'result': sleep_time }
2 changes: 2 additions & 0 deletions benchmarks/000.microbenchmarks/010.sleep/rust/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target/
bootstrap
14 changes: 14 additions & 0 deletions benchmarks/000.microbenchmarks/010.sleep/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "sleep-benchmark"
version = "0.1.0"
edition = "2021"
rust-version = "1.88"

# Note: This Cargo.toml only contains benchmark-specific dependencies.
# Wrapper dependencies (lambda_http, aws-sdk-*, etc.) are provided by the wrapper Cargo.toml
# and will be merged during the build process.

[dependencies]
# Benchmark-specific dependencies only
# serde is already in wrapper, but we can override features if needed
serde = { version = "1.0", features = ["derive"] }
24 changes: 24 additions & 0 deletions benchmarks/000.microbenchmarks/010.sleep/rust/src/function.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use serde::{Deserialize, Serialize};
use std::thread;
use std::time::Duration;

#[derive(Deserialize)]
pub struct RequestPayload {
pub sleep: Option<f64>,
}

#[derive(Serialize)]
pub struct FunctionResponse {
pub result: f64,
}

pub fn handler(event: RequestPayload) -> FunctionResponse {
let sleep_time = event.sleep.unwrap_or(0.0);
if sleep_time > 0.0 {
thread::sleep(Duration::from_secs_f64(sleep_time));
}

FunctionResponse {
result: sleep_time,
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"timeout": 30,
"memory": 128,
"languages": ["python"],
"modules": []
"languages": ["python", "pypy"],
"modules": ["storage"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import csv
import json
import os.path
import socket
from datetime import datetime
from time import sleep

import storage

def handler(event):

request_id = event['request-id']
address = event['server-address']
port = event['server-port']
repetitions = event['repetitions']
output_bucket = event.get('bucket').get('bucket')
output_prefix = event.get('bucket').get('output')
times = []
i = 0
socket.setdefaulttimeout(3)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('', 0))
message = request_id.encode('utf-8')
adr = (address, port)
consecutive_failures = 0
while i < repetitions + 1:
try:
send_begin = datetime.now().timestamp()
server_socket.sendto(message, adr)
msg, addr = server_socket.recvfrom(1024)
recv_end = datetime.now().timestamp()
except socket.timeout:
i += 1
consecutive_failures += 1
if consecutive_failures == 5:
print("Can't setup the connection")
break
continue
if i > 0:
times.append([i, send_begin, recv_end])
i += 1
consecutive_failures = 0
server_socket.settimeout(2)
server_socket.close()

if consecutive_failures != 5:
with open('/tmp/data.csv', 'w', newline='') as csvfile:
writer = csv.writer(csvfile, delimiter=',')
writer.writerow(["id", "client_send", "client_rcv"])
for row in times:
writer.writerow(row)

client = storage.storage.get_instance()
filename = 'results-{}.csv'.format(request_id)
key = client.upload(output_bucket, os.path.join(output_prefix, filename), '/tmp/data.csv')

return { 'result': key }
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"timeout": 30,
"memory": 128,
"languages": ["python"],
"modules": []
"languages": ["python", "pypy"],
"modules": ["storage"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import csv
import json
import os
import socket
from datetime import datetime
from time import sleep

import storage

def handler(event):

request_id = event['request-id']
address = event['server-address']
port = event['server-port']
repetitions = event['repetitions']
output_bucket = event.get('bucket').get('bucket')
output_prefix = event.get('bucket').get('output')
times = []
print("Starting communication with {}:{}".format(address, port))
i = 0
socket.setdefaulttimeout(4)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('', 0))
message = request_id.encode('utf-8')
adr = (address, port)
consecutive_failures = 0
measurements_not_smaller = 0
cur_min = 0
while i < 1000:
try:
send_begin = datetime.now().timestamp()
server_socket.sendto(message, adr)
msg, addr = server_socket.recvfrom(1024)
recv_end = datetime.now().timestamp()
except socket.timeout:
i += 1
consecutive_failures += 1
if consecutive_failures == 7:
print("Can't setup the connection")
break
continue
if i > 0:
times.append([i, send_begin, recv_end])
cur_time = recv_end - send_begin
print("Time {} Min Time {} NotSmaller {}".format(cur_time, cur_min, measurements_not_smaller))
if cur_time > cur_min and cur_min > 0:
measurements_not_smaller += 1
if measurements_not_smaller == repetitions:
message = "stop".encode('utf-8')
server_socket.sendto(message, adr)
break
else:
cur_min = cur_time
measurements_not_smaller = 0
i += 1
consecutive_failures = 0
server_socket.settimeout(4)
server_socket.close()

if consecutive_failures != 5:
with open('/tmp/data.csv', 'w', newline='') as csvfile:
writer = csv.writer(csvfile, delimiter=',')
writer.writerow(["id", "client_send", "client_rcv"])
for row in times:
writer.writerow(row)

client = storage.storage.get_instance()
filename = 'results-{}.csv'.format(request_id)
key = client.upload(output_bucket, os.path.join(output_prefix, filename), '/tmp/data.csv')
else:
key = None

return { 'result': {'bucket-key': key, 'timestamp': event['income-timestamp']} }
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

DIR=$1
VERBOSE=$2
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
cp ${SCRIPT_DIR}/file ${DIR}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"timeout": 120,
"memory": 128,
"languages": ["python", "nodejs"],
"languages": ["python", "nodejs", "pypy"],
"modules": []
}
13 changes: 13 additions & 0 deletions benchmarks/000.microbenchmarks/040.server-reply/pypy/function.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

import socket
from time import sleep

def handler(event):

# start timing
addr = (event.get('ip-address'), event.get('port'))
socket.setdefaulttimeout(20)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(addr)
msg = s.recv(1024).decode()
return {"result": msg}
2 changes: 1 addition & 1 deletion benchmarks/100.webapps/110.dynamic-html/config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"timeout": 10,
"memory": 128,
"languages": ["python", "nodejs"],
"languages": ["python", "nodejs", "java", "rust", "pypy"],
"modules": []
}
6 changes: 6 additions & 0 deletions benchmarks/100.webapps/110.dynamic-html/java/init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

OUTPUT_DIR=$1

# Copy templates directory to the output directory
cp -r templates "$OUTPUT_DIR/"
83 changes: 83 additions & 0 deletions benchmarks/100.webapps/110.dynamic-html/java/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>function</groupId>
<artifactId>dynamic-html</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- Mustache templating engine -->
<dependency>
<groupId>com.github.spullara.mustache.java</groupId>
<artifactId>compiler</artifactId>
<version>0.9.10</version>
</dependency>
<!-- AWS Lambda (required by wrapper) -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.3</version>
</dependency>
<!-- Azure Functions (required by wrapper) -->
<dependency>
<groupId>com.microsoft.azure.functions</groupId>
<artifactId>azure-functions-java-library</artifactId>
<version>3.0.0</version>
</dependency>
<!-- Jackson (required by wrapper) -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.1</version>
</dependency>
</dependencies>
<build>
<finalName>function</finalName>
<resources>
<resource>
<directory>${project.basedir}/templates</directory>
<targetPath>templates</targetPath>
<includes>
<include>**/*.html</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>module-info.class</exclude>
<exclude>META-INF/versions/*/module-info.class</exclude>
<exclude>META-INF/versions/**/module-info.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Loading