From 6425d898fdfe2ab1540f1af3adb3f37a0ae623f3 Mon Sep 17 00:00:00 2001 From: rhysd Date: Sat, 9 Nov 2019 23:05:29 +0900 Subject: [PATCH] add Go support --- action.yml | 2 +- config.ts | 14 +++++++------- examples/go/fib.go | 8 ++++++++ examples/go/fib_test.go | 17 +++++++++++++++++ extract.ts | 28 ++++++++++++++++++++++++++++ 5 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 examples/go/fib.go create mode 100644 examples/go/fib_test.go diff --git a/action.yml b/action.yml index 73a414ba8..b2cce58cb 100644 --- a/action.yml +++ b/action.yml @@ -8,7 +8,7 @@ inputs: required: true default: 'Benchmark' tool: - description: 'Tool to use get benchmark output. One of "cargo", ... (TODO)' + description: 'Tool to use get benchmark output. One of "cargo", "go"... (TODO)' required: true output-file-path: description: 'A path to file which contains the benchmark output' diff --git a/config.ts b/config.ts index 11b2ee970..c3ff9e47a 100644 --- a/config.ts +++ b/config.ts @@ -1,21 +1,21 @@ import * as core from '@actions/core'; -import {promises as fs, Stats} from 'fs'; +import { promises as fs, Stats } from 'fs'; import * as os from 'os'; import * as path from 'path'; -export type ToolType = 'cargo'; +export type ToolType = 'cargo' | 'go'; export interface Config { - name: string, + name: string; tool: ToolType; outputFilePath: string; ghPagesBranch: string; benchmarkDataDirPath: string; } -const VALID_TOOLS = ['cargo']; +const VALID_TOOLS: ToolType[] = ['cargo', 'go']; function validateToolType(tool: string): asserts tool is ToolType { - if (VALID_TOOLS.includes(tool)) { + if ((VALID_TOOLS as string[]).includes(tool)) { return; } throw new Error(`Invalid value '${tool}' for 'tool' input. It must be one of ${VALID_TOOLS}`); @@ -36,7 +36,7 @@ async function statPath(p: string): Promise<[Stats, string]> { p = resolvePath(p); try { return [await fs.stat(p), p]; - } catch(e) { + } catch (e) { throw new Error(`Cannot stat '${p}': ${e}`); } } @@ -63,7 +63,7 @@ function validateGhPagesBranch(branch: string) { function validateBenchmarkDataDirPath(dirPath: string): string { try { return resolvePath(dirPath); - } catch(e) { + } catch (e) { throw new Error(`Invalid value for 'benchmark-data-dir-path': ${e}`); } } diff --git a/examples/go/fib.go b/examples/go/fib.go new file mode 100644 index 000000000..21a3676a7 --- /dev/null +++ b/examples/go/fib.go @@ -0,0 +1,8 @@ +package fib + +func Fib(u uint) uint { + if u <= 1 { + return 1 + } + return Fib(u-2) + Fib(u-1) +} diff --git a/examples/go/fib_test.go b/examples/go/fib_test.go new file mode 100644 index 000000000..51c3777f2 --- /dev/null +++ b/examples/go/fib_test.go @@ -0,0 +1,17 @@ +package fib + +import ( + "testing" +) + +func BenchmarkFib10(b *testing.B) { + for i := 0; i < b.N; i++ { + var _ = Fib(10) + } +} + +func BenchmarkFib20(b *testing.B) { + for i := 0; i < b.N; i++ { + var _ = Fib(20) + } +} diff --git a/extract.ts b/extract.ts index a8a0fac82..dd561a4da 100644 --- a/extract.ts +++ b/extract.ts @@ -37,6 +37,8 @@ export interface Benchmark { function extractCargoResult(output: string): BenchmarkResult[] { const lines = output.split('\n'); const ret = []; + // Example: + // test bench_fib_20 ... bench: 37,174 ns/iter (+/- 7,527) const reExtract = /^test (\w+)\s+\.\.\. bench:\s+([0-9,]+) ns\/iter \(\+\/- ([0-9,]+)\)$/; const reComma = /,/g; @@ -61,6 +63,29 @@ function extractCargoResult(output: string): BenchmarkResult[] { return ret; } +function extractGoResult(output: string): BenchmarkResult[] { + const lines = output.split('\n'); + const ret = []; + // Example: + // BenchmarkFib20-8 30000 41653 ns/op + const reExtract = /^(Benchmark\w+)\S*\s+\d+\s+(\d+)\s+(.+)$/; + + for (const line of lines) { + const m = line.match(reExtract); + if (m === null) { + continue; + } + + const name = m[1]; + const value = parseInt(m[2], 10); + const unit = m[3]; + + ret.push({ name, value, unit }); + } + + return ret; +} + export async function extractResult(config: Config): Promise { const output = await fs.readFile(config.outputFilePath, 'utf8'); const { tool } = config; @@ -70,6 +95,9 @@ export async function extractResult(config: Config): Promise { case 'cargo': benches = extractCargoResult(output); break; + case 'go': + benches = extractGoResult(output); + break; default: throw new Error(`FATAL: Unexpected tool: '${tool}'`); }