Skip to content

Commit

Permalink
Refactor benchmark setup and enhance CSV generation logging (#112)
Browse files Browse the repository at this point in the history
This refactor splits the benchmark setup into two separate jobs for
better handling of individual configurations: one for Docker-based
benchmarks and another for PHP-based benchmarks. The jobs now support
testing with varying numbers of columns. In addition, the CSV generation
process now includes better-riched logs for easier debugging.
  • Loading branch information
SmetDenis committed Mar 29, 2024
1 parent 616337a commit c2444c7
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 41 deletions.
92 changes: 73 additions & 19 deletions .github/workflows/benchmark.yml
Expand Up @@ -10,41 +10,95 @@
# @see https://github.com/JBZoo/Csv-Blueprint
#

name: Stress Test
name: Speed Test

on:
pull_request:
branches:
- '*'
push:
branches:
- 'master'
workflow_dispatch:
inputs:
branch:
description: 'Branch Name'
required: true
default: 'master'

jobs:
stress-test:
name: Benchmark
docker-benchmark:
name: Docker
runs-on: ubuntu-latest
strategy:
matrix:
version: [ latest, local ]
columns: [ 1, 5, 10, 20 ]
env:
BENCH_COLS: ${{ matrix.columns }}
DOCKER_IMAGE: jbzoo/csv-blueprint:${{ matrix.version }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.inputs.branch }}
# ref: ${{ github.event.pull_request.head.ref }}

- name: Setup PHP
uses: shivammathur/setup-php@v2

# We need it to build benchmark tool. See ./tests/Benchmarks
- name: Build project
run: make build --no-print-directory

- name: Create random huge CSV files
run: make bench-create-csv --no-print-directory

- name: Building Docker Image
- name: Build local image
if: matrix.version == 'local'
uses: docker/build-push-action@v5
with:
context: .
push: false
tags: jbzoo/csv-blueprint:local
tags: ${{ env.DOCKER_IMAGE }}

- name: Pull latest image
if: matrix.version == 'latest'
run: docker pull ${{ env.DOCKER_IMAGE }}

- name: 🔥 Benchmark 🔥
run: make bench-create-csv bench-docker --no-print-directory


php-benchmark:
name: Phar
runs-on: ubuntu-latest
strategy:
matrix:
version: [ latest, local ]
columns: [ 1, 5, 10, 20 ]
env:
BENCH_COLS: ${{ matrix.columns }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.inputs.branch }}
# ref: ${{ github.event.pull_request.head.ref }}

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.3
coverage: none
ini-values: opcache.enable_cli=1, opcache.jit=1255

- name: Build local Phar file
if: matrix.version == 'local'
run: |
make build-prod build-phar-file --no-print-directory
./build/csv-blueprint.phar
- name: Download latest Phar file
if: matrix.version == 'latest'
run: |
wget https://github.com/JBZoo/Csv-Blueprint/releases/latest/download/csv-blueprint.phar -O ./build/csv-blueprint.phar
chmod +x ./build/csv-blueprint.phar
./build/csv-blueprint.phar
# We need it to build benchmark tool. See ./tests/Benchmarks
- name: Build project
run: make build --no-print-directory

- name: 🔥 Benchmark with Docker 🔥
run: make bench-docker --no-print-directory
- name: 🔥 Benchmark 🔥
run: make bench-create-csv bench-phar --no-print-directory
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Expand Up @@ -198,7 +198,7 @@ jobs:
verify-phar-binary:
name: Verify PHAR
name: Verify Phar
runs-on: ubuntu-latest
strategy:
matrix:
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/publish.yml
Expand Up @@ -18,7 +18,7 @@ on:

jobs:
phar:
name: Publish PHAR
name: Publish Phar
runs-on: ubuntu-latest
steps:
- name: Checkout code
Expand All @@ -36,10 +36,10 @@ jobs:
- name: Build project in production mode
run: make build-prod build-phar-file --no-print-directory

- name: 🎨 Test PHAR file
- name: 🎨 Test Phar file
run: ./build/csv-blueprint.phar --ansi -vvv

- name: Upload PHAR to the release
- name: Upload Phar to the release
uses: softprops/action-gh-release@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
Expand Down
17 changes: 11 additions & 6 deletions Makefile
Expand Up @@ -19,6 +19,7 @@ endif
DOCKER_IMAGE ?= jbzoo/csv-blueprint:local
CMD_VALIDATE := validate:csv --ansi
BLUEPRINT := COLUMNS=300 time $(PHP_BIN) ./csv-blueprint $(CMD_VALIDATE)
BLUEPRINT_PHAR := COLUMNS=300 time $(PHP_BIN) ./build/csv-blueprint.phar $(CMD_VALIDATE)
BLUEPRINT_DOCKER := time docker run --rm --workdir=/parent-host -v .:/parent-host $(DOCKER_IMAGE) $(CMD_VALIDATE)

VALID_CSV := --csv='./tests/fixtures/demo.csv'
Expand All @@ -37,7 +38,7 @@ build-prod: ##@Project Build project in production mode
@rm -f `pwd`/ci-report-converter
@make build-version

build-phar-file: ##@Project Build PHAR file
build-phar-file: ##@Project Build Phar file
curl -L "https://github.com/box-project/box/releases/download/4.5.1/box.phar" -o ./build/box.phar
@make build-version
@php ./build/box.phar --version
Expand Down Expand Up @@ -95,13 +96,12 @@ BENCH_SCHEMAS := --schema='./tests/Benchmarks/benchmark-*.yml'
BENCH_FLAGS := --debug --profile --report=text -vvv


bench-all: ##@Benchmarks Run all benchmarks
bench: ##@Benchmarks Run all benchmarks
@make bench-create-csv
@make docker-build
@make bench-docker

bench-create-csv: ##@Benchmarks Create CSV file
$(call title,"Benchmark - Create CSV file")
$(call title,"Benchmark - Create CSV file. Cols=${BENCH_COLS} Rows=${BENCH_ROWS_SRC}_000")
@mkdir -pv ./build/bench/
@rm -fv ./build/bench/*.csv
@time bash ./tests/Benchmarks/create-csv.sh
Expand All @@ -112,6 +112,11 @@ bench-docker: ##@Benchmarks Run CSV file with Docker
-$(BLUEPRINT_DOCKER) $(BENCH_CSV) $(BENCH_SCHEMAS) $(BENCH_FLAGS)


bench-php: ##@Benchmarks Run CSV file with PHP binary
$(call title,"Benchmark - CSV file with PHP binary")
bench-phar: ##@Benchmarks Run CSV file with Phar
$(call title,"Benchmark - CSV file with Phar")
-$(BLUEPRINT_PHAR) $(BENCH_CSV) $(BENCH_SCHEMAS) $(BENCH_FLAGS)


bench-php: ##@Benchmarks Run CSV file with classic PHP binary
$(call title,"Benchmark - CSV file with classic PHP binary")
-$(BLUEPRINT) $(BENCH_CSV) $(BENCH_SCHEMAS) $(BENCH_FLAGS)
7 changes: 1 addition & 6 deletions src/Rules/Ruleset.php
Expand Up @@ -56,12 +56,7 @@ public function validateRuleSet(array|string $cellValue, int $line, int $linesTo
$errors->addError($rule->validate($cellValue, $line));

if ($linesToAggregate > 0) {
Utils::debug(
" {$rule->getRuleCode()} - "
. '<blue>'
. \number_format($linesToAggregate / (\microtime(true) - $startTimer))
. '</blue> l/s',
);
Utils::debugSpeed(" {$rule->getRuleCode()} -", $linesToAggregate, $startTimer);
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/Utils.php
Expand Up @@ -61,6 +61,12 @@ public static function debug(int|string $message): void
}
}

public static function debugSpeed(string $messPrefix, int $lines, float $startTimer): void
{
$kiloLines = \round(($lines / (\microtime(true) - $startTimer)) / 1000);
self::debug("{$messPrefix} <blue>" . \number_format($kiloLines) . 'K</blue> lines/sec');
}

public static function kebabToCamelCase(string $input): string
{
return \str_replace(' ', '', \ucwords(\str_replace(['-', '_'], ' ', $input)));
Expand Down
7 changes: 1 addition & 6 deletions src/Validators/ValidatorCsv.php
Expand Up @@ -165,12 +165,7 @@ private function validateLines(bool $quickStop = false): ErrorSuite
}
}
Utils::debug("{$messPrefix} Lines <yellow>" . \number_format($lineCounter) . '</yellow>');
Utils::debug(
"{$messPrefix} <yellow>Speed:cell</yellow> "
. '<blue>'
. \number_format($lineCounter / (\microtime(true) - $startTimer))
. '</blue> l/s',
);
Utils::debugSpeed($messPrefix, $lineCounter, $startTimer);

if ($isAggRules) { // Time optimization
$errors->addErrorSuit($colValidator->validateList($columValues, $lineCounter));
Expand Down
4 changes: 4 additions & 0 deletions tests/Benchmarks/create-csv.sh
Expand Up @@ -25,6 +25,10 @@ for i in {1..1000}; do
cat ./build/bench/${BENCH_COLS}_${BENCH_ROWS_SRC}.csv >> $BENCH_CSV_PATH
done

echo "----"
echo $BENCH_CSV_PATH
head $BENCH_CSV_PATH

echo "----"
echo "File size : $(du -h $BENCH_CSV_PATH)"
echo "Rows count: $(wc -l $BENCH_CSV_PATH)"
Expand Down

0 comments on commit c2444c7

Please sign in to comment.