blob: cd1d938709d6bfab40efdf6bd2c735b3f032c22f [file]
#!/bin/bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
set -euo pipefail
export ENABLE_FORY_DEBUG_OUTPUT=0
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
PYTHON_BIN="${PYTHON_BIN:-python3}"
OUTPUT_DIR="$SCRIPT_DIR/results"
REPORT_DIR="$OUTPUT_DIR/report"
PROTO_DIR="$SCRIPT_DIR/proto"
DOCS_DIR="$SCRIPT_DIR/../../docs/benchmarks/python"
DATA=""
SERIALIZER=""
OPERATION="all"
WARMUP=3
ITERATIONS=15
REPEAT=5
NUMBER=1000
COPY_DOCS=true
usage() {
cat <<'EOF'
Usage: ./run.sh [options]
Run Python comprehensive benchmarks for struct/sample/mediacontent and list variants.
Options:
--data <type> Filter by data type: struct,sample,mediacontent,structlist,samplelist,mediacontentlist
--serializer <name> Filter by serializer: fory,pickle,protobuf
--operation <op> all|serialize|deserialize (default: all)
--warmup <n> Warmup iterations (default: 3)
--iterations <n> Measurement iterations (default: 15)
--repeat <n> Repeat count per iteration (default: 5)
--number <n> Inner loop call count (default: 1000)
--no-copy-docs Skip copying report/plots into docs/benchmarks/python
-h, --help Show this help message
Examples:
./run.sh
./run.sh --data struct --serializer fory
./run.sh --operation serialize --iterations 30 --repeat 8
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--data)
DATA="$2"
shift 2
;;
--serializer)
SERIALIZER="$2"
shift 2
;;
--operation)
OPERATION="$2"
shift 2
;;
--warmup)
WARMUP="$2"
shift 2
;;
--iterations)
ITERATIONS="$2"
shift 2
;;
--repeat)
REPEAT="$2"
shift 2
;;
--number)
NUMBER="$2"
shift 2
;;
--no-copy-docs)
COPY_DOCS=false
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown option: $1"
usage
exit 1
;;
esac
done
if [[ "${FORY_BENCH_SCHEMA_MISMATCH:-0}" == "1" && "$SERIALIZER" != "fory" ]]; then
echo "FORY_BENCH_SCHEMA_MISMATCH=1 supports only Fory benchmarks; rerun with --serializer fory."
exit 1
fi
if ! command -v "$PYTHON_BIN" >/dev/null 2>&1; then
echo "Error: $PYTHON_BIN is not available"
exit 1
fi
if ! command -v protoc >/dev/null 2>&1; then
echo "Error: protoc is required. Install protobuf compiler first."
echo " macOS: brew install protobuf"
exit 1
fi
echo "============================================"
echo "Python Comprehensive Benchmark"
echo "============================================"
echo "Checking runtime dependencies..."
if ! "$PYTHON_BIN" -c "import pyfory" >/dev/null 2>&1; then
echo "Error: pyfory is not installed in current Python environment."
echo "Install it with: cd python && pip install -e ."
exit 1
fi
if ! "$PYTHON_BIN" -c "import google.protobuf" >/dev/null 2>&1; then
echo "Installing benchmark dependency: protobuf"
"$PYTHON_BIN" -m pip install protobuf
fi
if ! "$PYTHON_BIN" -c "import matplotlib, numpy" >/dev/null 2>&1; then
echo "Installing report dependencies: matplotlib numpy psutil"
"$PYTHON_BIN" -m pip install matplotlib numpy psutil
fi
mkdir -p "$PROTO_DIR" "$OUTPUT_DIR" "$REPORT_DIR"
if [[ ! -f "$PROTO_DIR/__init__.py" ]]; then
touch "$PROTO_DIR/__init__.py"
fi
echo "Generating Python protobuf bindings..."
protoc \
--proto_path="$SCRIPT_DIR/../proto" \
--python_out="$PROTO_DIR" \
"$SCRIPT_DIR/../proto/bench.proto"
BENCH_JSON="$OUTPUT_DIR/benchmark_results.json"
BENCH_CMD=(
"$PYTHON_BIN" "$SCRIPT_DIR/benchmark.py"
--proto-dir "$PROTO_DIR"
--output-json "$BENCH_JSON"
--operation "$OPERATION"
--warmup "$WARMUP"
--iterations "$ITERATIONS"
--repeat "$REPEAT"
--number "$NUMBER"
)
if [[ -n "$DATA" ]]; then
BENCH_CMD+=(--data "$DATA")
fi
if [[ -n "$SERIALIZER" ]]; then
BENCH_CMD+=(--serializer "$SERIALIZER")
fi
echo ""
echo "Running benchmark..."
"${BENCH_CMD[@]}"
echo ""
echo "Generating report..."
"$PYTHON_BIN" "$SCRIPT_DIR/benchmark_report.py" \
--json-file "$BENCH_JSON" \
--output-dir "$REPORT_DIR"
if [[ "$COPY_DOCS" == true ]]; then
mkdir -p "$DOCS_DIR"
cp "$REPORT_DIR/README.md" "$DOCS_DIR/README.md"
cp "$REPORT_DIR/throughput.png" "$DOCS_DIR/throughput.png"
echo "Copied report and throughput plot to: $DOCS_DIR"
fi
echo ""
echo "============================================"
echo "Benchmark complete!"
echo "============================================"
echo "Benchmark JSON: $BENCH_JSON"
echo "Report: $REPORT_DIR/README.md"
if [[ "$COPY_DOCS" == true ]]; then
echo "Docs sync: $DOCS_DIR"
fi