Skip to content

Commit

Permalink
feat(cli): support performance statistic
Browse files Browse the repository at this point in the history
  • Loading branch information
pionxzh committed Dec 14, 2023
1 parent d3b3da8 commit 771b639
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 14 deletions.
48 changes: 37 additions & 11 deletions packages/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ import yargs from 'yargs'
import { hideBin } from 'yargs/helpers'
import { version } from '../package.json'
import { findCommonBaseDir, getRelativePath, isPathInside, resolveGlob } from './path'
import { Timing } from './perf'
import { Timing } from './timing'
import { unpacker } from './unpacker'
import type { Measurement } from './timing'
import type { UnminifyWorkerParams } from './types'
import type { ModuleMapping, ModuleMeta } from '@wakaru/ast-utils/types'
import type { Module } from '@wakaru/unpacker'
Expand Down Expand Up @@ -127,7 +128,7 @@ async function interactive({
output: _output,
force: _force = false,
concurrency = 1,
// perf,
perf,
}: {
inputs: string[] | undefined
output: string | undefined
Expand Down Expand Up @@ -395,10 +396,10 @@ async function interactive({
s.start('...')

const timing = new Timing()
const pool = new FixedThreadPool<UnminifyWorkerParams, void>(concurrency, unminifyWorkerFile, {
const pool = new FixedThreadPool<UnminifyWorkerParams, Measurement>(concurrency, unminifyWorkerFile, {
errorHandler: e => console.error(e),
})
const execute = async (inputPath: string) => {
const unminify = async (inputPath: string) => {
const outputPath = path.join(outputDir, path.relative(commonBaseDir, inputPath))
const result = await pool.execute({
inputPath,
Expand All @@ -409,10 +410,22 @@ async function interactive({
s.message(`${c.green(path.relative(cwd, inputPath))}`)
return result
}
const { time: elapsed } = await timing.measureTimeAsync(() => Promise.all(
unminifyInputPaths.map(p => execute(p)),
const { result: measurements, time: elapsed } = await timing.measureTimeAsync(() => Promise.all(
unminifyInputPaths.map(p => unminify(p)),
))

if (perf) {
const groupedByRules = measurements
.flat()
.reduce<Record<string, number>>((acc, { key, time }) => {
acc[key] = (acc[key] ?? 0) + time
return acc
}, {})
const table = Object.entries(groupedByRules)
.map(([key, time]) => ({ key, time: ~~time }))
.sort((a, b) => a.time - b.time)
console.table(table, ['key', 'time'])
}
s.stop('Finished')

const formattedElapsed = elapsed.toLocaleString('en-US', { maximumFractionDigits: 1 })
Expand All @@ -434,7 +447,7 @@ async function nonInteractive(features: Feature[], {
'unminify-output': _unminifyOutput,
force = false,
concurrency = 1,
// perf,
perf,
}: {
inputs: string[] | undefined
output: string | undefined
Expand Down Expand Up @@ -568,10 +581,10 @@ async function nonInteractive(features: Feature[], {

const timing = new Timing()

const pool = new FixedThreadPool<UnminifyWorkerParams, void>(concurrency, unminifyWorkerFile, {
const pool = new FixedThreadPool<UnminifyWorkerParams, Measurement>(concurrency, unminifyWorkerFile, {
errorHandler: e => console.error(e),
})
const execute = async (inputPath: string) => {
const unminify = async (inputPath: string) => {
const outputPath = path.join(outputDir, path.relative(commonBaseDir, inputPath))
const result = await pool.execute({
inputPath,
Expand All @@ -582,10 +595,23 @@ async function nonInteractive(features: Feature[], {
s.message(`${c.green(path.relative(cwd, inputPath))}`)
return result
}
const { time: elapsed } = await timing.measureTimeAsync(() => Promise.all(
unminifyInputPaths.map(p => execute(p)),
const { result: measurements, time: elapsed } = await timing.measureTimeAsync(() => Promise.all(
unminifyInputPaths.map(p => unminify(p)),
))

if (perf) {
const groupedByRules = measurements
.flat()
.reduce<Record<string, number>>((acc, { key, time }) => {
acc[key] = (acc[key] ?? 0) + time
return acc
}, {})
const table = Object.entries(groupedByRules)
.map(([key, time]) => ({ key, time: ~~time }))
.sort((a, b) => a.time - b.time)
console.table(table, ['key', 'time'])
}

pool.destroy()

s.stop('Finished')
Expand Down
6 changes: 6 additions & 0 deletions packages/cli/src/perf.ts → packages/cli/src/timing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ interface TimingStat {
time: number
}

export type Measurement = TimingStat[]

export class Timing {
private collected: TimingStat[] = []

Expand Down Expand Up @@ -64,4 +66,8 @@ export class Timing {

return { result, time }
}

getMeasurements(): Measurement {
return this.collected
}
}
7 changes: 5 additions & 2 deletions packages/cli/src/unminify.worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import process from 'node:process'
import { runTransformations, transformationRules } from '@wakaru/unminify'
import fsa from 'fs-extra'
import { ThreadWorker } from 'poolifier'
import { Timing } from './perf'
import { Timing } from './timing'
import type { Measurement } from './timing'
import type { UnminifyWorkerParams } from './types'
import type { Transform } from 'jscodeshift'

Expand All @@ -27,6 +28,8 @@ export async function unminify(data?: UnminifyWorkerParams) {
const { code } = runTransformations(fileInfo, transformations, { moduleMeta, moduleMapping })
await fsa.ensureFile(outputPath)
await fsa.writeFile(outputPath, code, 'utf-8')

return timing.getMeasurements()
}
catch (e) {
// We print the error here because it will lose the stack trace after being sent to the main thread
Expand All @@ -35,4 +38,4 @@ export async function unminify(data?: UnminifyWorkerParams) {
}
}

export default new ThreadWorker<UnminifyWorkerParams, void>(unminify)
export default new ThreadWorker<UnminifyWorkerParams, Measurement>(unminify)
2 changes: 1 addition & 1 deletion packages/cli/src/unpacker.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'node:path'
import { unpack } from '@wakaru/unpacker'
import fsa from 'fs-extra'
import { Timing } from './perf'
import { Timing } from './timing'
import type { ModuleMapping } from '@wakaru/ast-utils/types'
import type { Module } from '@wakaru/unpacker'

Expand Down

0 comments on commit 771b639

Please sign in to comment.