generated from yamiteru/ts-package
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
455 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { Offsets, Options } from "./types"; | ||
|
||
export const OPTIONS = { | ||
cpu: { | ||
chunkSize: 100, | ||
compareSize: 10, | ||
rangePercent: 10, | ||
}, | ||
ram: { | ||
chunkSize: 5, | ||
compareSize: 5, | ||
rangePercent: 5, | ||
}, | ||
general: { | ||
substractSelf: true, | ||
allowGc: true, | ||
} | ||
} satisfies Options; | ||
|
||
export const OFFSETS = { | ||
async: { | ||
cpu: { | ||
min: 0, | ||
max: 0, | ||
median: 0, | ||
}, | ||
ram: { | ||
min: 0, | ||
max: 0, | ||
median: 0, | ||
}, | ||
}, | ||
sync: { | ||
cpu: { | ||
min: 0, | ||
max: 0, | ||
median: 0, | ||
}, | ||
ram: { | ||
min: 0, | ||
max: 0, | ||
median: 0, | ||
}, | ||
} | ||
} satisfies Offsets; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { Options, Stores } from "./types"; | ||
|
||
// memoize store by options and reuse it if possible | ||
export function createStores(options: Options): Stores { | ||
return { | ||
cpu: { | ||
chunk: { | ||
array: new Uint32Array(new ArrayBuffer(options.cpu.chunkSize * 4)), | ||
index: 0 | ||
}, | ||
main: { | ||
array: new Uint32Array(new ArrayBuffer(options.cpu.chunkSize * 4)), | ||
index: 0 | ||
}, | ||
}, | ||
ram: { | ||
chunk: { | ||
array: new Uint32Array(new ArrayBuffer(options.ram.chunkSize * 4)), | ||
index: 0 | ||
}, | ||
main: { | ||
array: new Uint32Array(new ArrayBuffer(options.ram.chunkSize * 4)), | ||
index: 0 | ||
}, | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { getOffset } from "./getOffset"; | ||
import { Offsets, Options, Stores } from "./types"; | ||
|
||
export async function getAllOffsets( | ||
stores: Stores, | ||
options: Options | ||
): Promise<Offsets> { | ||
return { | ||
async: { | ||
cpu: await getOffset({ type: "async", mode: "cpu" }, stores, options), | ||
ram: await getOffset({ type: "async", mode: "ram" }, stores, options), | ||
}, | ||
sync: { | ||
cpu: await getOffset({ type: "sync", mode: "cpu" }, stores, options), | ||
ram: await getOffset({ type: "sync", mode: "ram" }, stores, options), | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { getMedian } from "./getMedian"; | ||
import { getMinMax } from "./getMinMax"; | ||
import { positive } from "./positive"; | ||
import { OffsetData, Offsets, Store } from "./types"; | ||
|
||
export function getCpuStats( | ||
{ array, index }: Store, | ||
{ mode, type }: OffsetData, | ||
offsets: Offsets | ||
) { | ||
const median = getMedian(array, index); | ||
const { min, max } = getMinMax(array, index); | ||
const ctx = offsets[type][mode]; | ||
|
||
return { | ||
median: positive(median - ctx.median), | ||
min: positive(min - ctx.min), | ||
max: positive(max - ctx.max) | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export function getMedian( | ||
array: Uint32Array, | ||
length: number | ||
) { | ||
return array | ||
.slice(0, length) | ||
.sort() | ||
.at(Math.floor(length / 2)) as number; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
export function getMinMax( | ||
array: Uint32Array, | ||
length: number | ||
) { | ||
let min = array[0]; | ||
let max = array[0]; | ||
|
||
for(let i = 1; i < length; ++i) { | ||
const value = array[i]; | ||
|
||
if(value < min) min = value; | ||
if(value > max) max = value; | ||
} | ||
|
||
return { min, max }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { OFFSETS } from "./constants"; | ||
import { getCpuStats } from "./getCpuStats"; | ||
import { getMedian } from "./getMedian"; | ||
import { getMinMax } from "./getMinMax"; | ||
import { getRamStats } from "./getRamStats"; | ||
import { measure } from "./measure"; | ||
import { OffsetData, Options, Stores } from "./types"; | ||
|
||
// TODO: use "run" function to get rid of duplication | ||
// TODO: run as many times as needed to get to zero | ||
export async function getOffset( | ||
{ type, mode }: OffsetData, | ||
stores: Stores, | ||
options: Options | ||
) { | ||
const { chunk, main } = stores[mode]; | ||
const { chunkSize, compareSize, rangePercent } = options[mode]; | ||
const getStats = mode === "cpu" ? getCpuStats: getRamStats; | ||
const fn = type === "async" ? async () => { /* */ }: () => { /* */ }; | ||
|
||
main.index = -1; | ||
chunk.index = -1; | ||
|
||
while(true as any) { | ||
if(chunk.index === chunkSize) { | ||
main.array[++main.index] = getMedian(chunk.array, chunk.index); | ||
chunk.index = -1; | ||
|
||
if(main.index >= compareSize) { | ||
const { min, max } = getMinMax( | ||
main.array.slice(main.index - compareSize), | ||
compareSize | ||
); | ||
|
||
if((max - (max / 100 * rangePercent)) <= min) { | ||
break; | ||
} | ||
} | ||
} | ||
|
||
if(main.index === chunkSize) { | ||
main.array[0] = getMedian(main.array, main.index); | ||
main.index = 0; | ||
} | ||
|
||
await measure({ fn, mode, store: chunk }, options); | ||
} | ||
|
||
return getStats(main, { mode, type: fn instanceof Promise ? "async": "sync" }, OFFSETS); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { OPTIONS } from "./constants"; | ||
import { DeepPartial, Options } from "./types"; | ||
|
||
export function getOptions( | ||
partialOptions?: DeepPartial<Options> | ||
) { | ||
return { | ||
cpu: { | ||
...OPTIONS.cpu, | ||
...(partialOptions?.cpu || {}) | ||
}, | ||
ram: { | ||
...OPTIONS.ram, | ||
...(partialOptions?.ram || {}) | ||
}, | ||
general: { | ||
...OPTIONS.general, | ||
...(partialOptions?.general || {}) | ||
} | ||
} satisfies Options; | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { getMedian } from "./getMedian"; | ||
import { getMinMax } from "./getMinMax"; | ||
import { positive } from "./positive"; | ||
import { OffsetData, Offsets, Store } from "./types"; | ||
|
||
export function getRamStats( | ||
{ array, index }: Store, | ||
{ mode, type }: OffsetData, | ||
offsets: Offsets | ||
) { | ||
const median = getMedian(array, index); | ||
const { min, max } = getMinMax(array, index); | ||
const ctx = offsets[type][mode]; | ||
|
||
return { | ||
median: positive(median - ctx.median), | ||
min: positive(min - ctx.min), | ||
max: positive(max - ctx.max) | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,13 @@ | ||
export const add = (...n: number[]) => n.reduce((acc, v) => acc + v, 0); | ||
import { preset } from "./preset"; | ||
|
||
const defaultSuite = preset(); | ||
const callibration = defaultSuite({ | ||
emptySync: () => { /* */ }, | ||
emptyAsync: async () => { /* */ }, | ||
}); | ||
|
||
(async () => { | ||
for await (const result of callibration()) { | ||
console.log(result); | ||
} | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { MeasureData, Options } from "./types"; | ||
|
||
export async function measure( | ||
{ fn, mode, store }: MeasureData, | ||
{ general: { allowGc } }: Options | ||
) { | ||
const isAsync = fn instanceof Promise; | ||
|
||
if(mode === "cpu") { | ||
const start = process.hrtime.bigint(); | ||
|
||
isAsync ? (await fn()): fn(); | ||
|
||
const end = process.hrtime.bigint(); | ||
|
||
store.array[++store.index] = Math.round(Number(end - start)); | ||
} else { | ||
allowGc && global.gc?.(); | ||
|
||
const start = process.memoryUsage().heapUsed; | ||
|
||
isAsync ? (await fn()): fn(); | ||
|
||
const end = process.memoryUsage().heapUsed; | ||
|
||
store.array[++store.index] = Math.round(Number(end - start)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export function positive(value: number) { | ||
return value < 0 ? 0: value; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { createStores } from "./createStores"; | ||
import { getAllOffsets } from "./getAllOffsets"; | ||
import { getOptions } from "./getOptions"; | ||
import { runBenchmark } from "./runBenchmark"; | ||
import { DeepPartial, Options, Benchmarks } from "./types"; | ||
|
||
export function preset(partialOptions?: DeepPartial<Options>) { | ||
const options = getOptions(partialOptions); | ||
const stores = createStores(options); | ||
|
||
return function createSuite< | ||
$Benchmarks extends Benchmarks | ||
>( | ||
benchmarks: $Benchmarks | ||
) { | ||
return async function* runSuite() { | ||
const offsets = await getAllOffsets(stores, options); | ||
|
||
console.log(offsets); | ||
|
||
for(const benchmarkName in benchmarks) { | ||
options.general.allowGc && global.gc?.(); | ||
|
||
yield await runBenchmark( | ||
benchmarks[benchmarkName], | ||
stores, | ||
offsets, | ||
options | ||
); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { getCpuStats } from "./getCpuStats"; | ||
import { getMedian } from "./getMedian"; | ||
import { getMinMax } from "./getMinMax"; | ||
import { getRamStats } from "./getRamStats"; | ||
import { measure } from "./measure"; | ||
import { Benchmark, OffsetData, Offsets, Options, Stores } from "./types"; | ||
|
||
export async function run( | ||
fn: Benchmark, | ||
mode: OffsetData["mode"], | ||
stores: Stores, | ||
offsets: Offsets, | ||
options: Options | ||
) { | ||
const { chunk, main } = stores[mode]; | ||
const { chunkSize, compareSize, rangePercent } = options[mode]; | ||
const getStats = mode === "cpu" | ||
? getCpuStats | ||
: getRamStats; | ||
|
||
main.index = -1; | ||
chunk.index = -1; | ||
|
||
while(true as any) { | ||
if(chunk.index === chunkSize) { | ||
main.array[++main.index] = getMedian(chunk.array, chunk.index); | ||
chunk.index = -1; | ||
|
||
if(main.index >= compareSize) { | ||
const { min, max } = getMinMax( | ||
main.array.slice(main.index - compareSize), | ||
compareSize | ||
); | ||
|
||
if((max - (max / 100 * rangePercent)) <= min) { | ||
break; | ||
} | ||
} | ||
} | ||
|
||
if(main.index === chunkSize) { | ||
main.array[0] = getMedian(main.array, main.index); | ||
main.index = 0; | ||
} | ||
|
||
await measure({ fn, mode, store: chunk }, options); | ||
} | ||
|
||
return getStats(main, { mode, type: fn instanceof Promise ? "async": "sync" }, offsets); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { run } from "./run"; | ||
import { Benchmark, Offsets, Options, Stores } from "./types"; | ||
|
||
export async function runBenchmark( | ||
benchmark: Benchmark, | ||
stores: Stores, | ||
offsets: Offsets, | ||
options: Options | ||
) { | ||
return { | ||
cpu: await run(benchmark, "cpu", stores, offsets, options), | ||
ram: await run(benchmark, "ram", stores, offsets, options) | ||
}; | ||
} |
Oops, something went wrong.