| #!/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 -e |
| |
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| cd "$SCRIPT_DIR" |
| |
| # Colors for output |
| RED='\033[0;31m' |
| GREEN='\033[0;32m' |
| YELLOW='\033[1;33m' |
| NC='\033[0m' # No Color |
| |
| # Default values |
| JOBS=16 |
| DATA="" |
| SERIALIZER="" |
| DEBUG_BUILD=false |
| |
| # Parse arguments |
| usage() { |
| echo "Usage: $0 [OPTIONS]" |
| echo "" |
| echo "Build and run C++ benchmarks" |
| echo "" |
| echo "Options:" |
| echo " --data <struct|sample> Filter benchmark by data type" |
| echo " --serializer <fory|protobuf> Filter benchmark by serializer" |
| echo " --debug Build with debug symbols and low optimization for profiling" |
| echo " --help Show this help message" |
| echo "" |
| echo "Examples:" |
| echo " $0 # Run all benchmarks" |
| echo " $0 --data struct # Run only Struct benchmarks" |
| echo " $0 --serializer fory # Run only Fory benchmarks" |
| echo " $0 --data struct --serializer fory" |
| echo " $0 --debug # Build for profiling (visible function names in flamegraph)" |
| echo "" |
| echo "For profiling/flamegraph, use: ./profile.sh" |
| exit 0 |
| } |
| |
| while [[ $# -gt 0 ]]; do |
| case $1 in |
| --data) |
| DATA="$2" |
| shift 2 |
| ;; |
| --serializer) |
| SERIALIZER="$2" |
| shift 2 |
| ;; |
| --debug) |
| DEBUG_BUILD=true |
| shift |
| ;; |
| --help|-h) |
| usage |
| ;; |
| *) |
| echo -e "${RED}Unknown option: $1${NC}" |
| usage |
| ;; |
| esac |
| done |
| |
| # Build benchmark filter |
| FILTER="" |
| if [[ -n "$DATA" ]]; then |
| DATA_CAP="$(echo "${DATA:0:1}" | tr '[:lower:]' '[:upper:]')${DATA:1}" |
| FILTER="${DATA_CAP}" |
| fi |
| if [[ -n "$SERIALIZER" ]]; then |
| SER_CAP="$(echo "${SERIALIZER:0:1}" | tr '[:lower:]' '[:upper:]')${SERIALIZER:1}" |
| if [[ -n "$FILTER" ]]; then |
| FILTER="${SER_CAP}_${FILTER}" |
| else |
| FILTER="${SER_CAP}" |
| fi |
| fi |
| |
| echo -e "${GREEN}=== Fory C++ Benchmark ===${NC}" |
| echo "" |
| |
| # Step 1: Build |
| echo -e "${YELLOW}[1/3] Building benchmark...${NC}" |
| mkdir -p build |
| cd build |
| if [[ "$DEBUG_BUILD" == true ]]; then |
| echo -e "${YELLOW}Building with debug symbols for profiling...${NC}" |
| # Detect OS for platform-specific flags |
| OS_TYPE="$(uname -s)" |
| if [[ "$OS_TYPE" == "Darwin" ]]; then |
| # macOS: Use -gfull for complete debug info, -fno-omit-frame-pointer for stack traces |
| cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo \ |
| -DCMAKE_CXX_FLAGS="-O1 -gfull -fno-inline -fno-omit-frame-pointer -fno-optimize-sibling-calls" .. |
| else |
| # Linux |
| cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo \ |
| -DCMAKE_CXX_FLAGS="-O1 -g -fno-inline -fno-omit-frame-pointer" .. |
| fi |
| else |
| cmake -DCMAKE_BUILD_TYPE=Release .. |
| fi |
| cmake --build . -j"$JOBS" |
| echo -e "${GREEN}Build complete!${NC}" |
| echo "" |
| |
| # Step 2: Run benchmark |
| echo -e "${YELLOW}[2/3] Running benchmark...${NC}" |
| BENCH_ARGS="--benchmark_format=json --benchmark_out=benchmark_results.json" |
| if [[ -n "$FILTER" ]]; then |
| BENCH_ARGS="$BENCH_ARGS --benchmark_filter=$FILTER" |
| echo -e "Filter: ${FILTER}" |
| fi |
| ./fory_benchmark $BENCH_ARGS |
| echo -e "${GREEN}Benchmark complete!${NC}" |
| echo "" |
| |
| # Step 3: Generate report |
| echo -e "${YELLOW}[3/3] Generating report...${NC}" |
| cd "$SCRIPT_DIR" |
| |
| # Check for Python dependencies |
| if ! python3 -c "import matplotlib" 2>/dev/null; then |
| echo -e "${YELLOW}Installing required Python packages...${NC}" |
| pip3 install matplotlib numpy psutil |
| fi |
| |
| python3 benchmark_report.py --json-file build/benchmark_results.json --output-dir report |
| echo "" |
| |
| echo -e "${GREEN}=== All done! ===${NC}" |
| echo -e "Report generated at: ${SCRIPT_DIR}/report/REPORT.md" |
| echo -e "Plots saved in: ${SCRIPT_DIR}/report/" |
| echo "" |
| echo -e "For profiling/flamegraph, run: ${YELLOW}./profile.sh --help${NC}" |