Skip to content

Commit

Permalink
chore: introduce native glob benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
mrmlnc committed Jan 3, 2025
1 parent bbc7d07 commit 22a5d5a
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 2 deletions.
33 changes: 32 additions & 1 deletion src/benchmark/suites/product/async.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as bencho from 'bencho';

import * as utils from '../../utils';

type GlobImplementation = 'fast-glob' | 'node-glob' | 'tinyglobby';
type GlobImplementation = 'fast-glob' | 'native' | 'node-glob' | 'tinyglobby';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type GlobImplFunction = (...args: any[]) => Promise<unknown[]>;

Expand All @@ -17,6 +17,32 @@ class Glob {
this.#pattern = pattern;
}

/**
* Assumptions:
*
* 1. The implementation returns entries with an absolute path, while all other solutions return a relative path.
*/
public async measureNative(): Promise<void> {
const glob = await utils.importAndMeasure(utils.importNativeGlob);

await this.#measure(async () => {
const iterator = await glob.glob(this.#pattern, {
cwd: this.#cwd,
withFileTypes: true,
});

const entries: string[] = [];

for await (const dirent of iterator) {
if (!dirent.isDirectory()) {
entries.push(`${dirent.parentPath}/${dirent.name}`);
}
}

return entries;
});
}

public async measureNodeGlob(): Promise<void> {
const glob = await utils.importAndMeasure(utils.importNodeGlob);

Expand Down Expand Up @@ -71,6 +97,11 @@ class Glob {
const glob = new Glob(cwd, pattern);

switch (impl) {
case 'native': {
await glob.measureNative();
break;
}

case 'node-glob': {
await glob.measureNodeGlob();
break;
Expand Down
33 changes: 32 additions & 1 deletion src/benchmark/suites/product/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as bencho from 'bencho';

import * as utils from '../../utils';

type GlobImplementation = 'fast-glob' | 'node-glob' | 'tinyglobby';
type GlobImplementation = 'fast-glob' | 'native' | 'node-glob' | 'tinyglobby';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type GlobImplFunction = (...args: any[]) => unknown[];

Expand All @@ -17,6 +17,32 @@ class Glob {
this.#pattern = pattern;
}

/**
* Assumptions:
*
* 1. The implementation returns entries with an absolute path, while all other solutions return a relative path.
*/
public async measureNative(): Promise<void> {
const glob = await utils.importAndMeasure(utils.importNativeGlob);

this.#measure(() => {
const iterator = glob.globSync(this.#pattern, {
cwd: this.#cwd,
withFileTypes: true,
});

const entries: string[] = [];

for (const dirent of iterator) {
if (!dirent.isDirectory()) {
entries.push(`${dirent.parentPath}/${dirent.name}`);
}
}

return entries;
});
}

public async measureNodeGlob(): Promise<void> {
const glob = await utils.importAndMeasure(utils.importNodeGlob);

Expand Down Expand Up @@ -71,6 +97,11 @@ class Glob {
const glob = new Glob(cwd, pattern);

switch (impl) {
case 'native': {
await glob.measureNative();
break;
}

case 'node-glob': {
await glob.measureNodeGlob();
break;
Expand Down
25 changes: 25 additions & 0 deletions src/benchmark/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,22 @@ import { performance } from 'node:perf_hooks';

import * as bencho from 'bencho';

import type * as fs from 'node:fs';
import type * as currentVersion from '..';
import type * as previousVersion from 'fast-glob';
import type * as glob from 'glob';
import type * as tg from 'tinyglobby';

type NativeGlobAsynchronous = (pattern: string, options: {
cwd: string;
withFileTypes: boolean;
}) => Promise<AsyncIterable<fs.Dirent>>;

type NativeGlobSynchronous = (pattern: string, options: {
cwd: string;
withFileTypes: boolean;
}) => fs.Dirent[];

export function timeStart(): number {
return performance.now();
}
Expand All @@ -23,6 +34,20 @@ export function importCurrentFastGlob(): Promise<typeof currentVersion> {
return import('..');
}

export async function importNativeGlob(): Promise<{
glob: NativeGlobAsynchronous;
globSync: NativeGlobSynchronous;
}> {
const fs = await import('node:fs');

return {
// @ts-expect-error The current version of @types/node has not definitions for this method.
glob: fs.promises.glob as NativeGlobAsynchronous,
// @ts-expect-error The current version of @types/node has not definitions for this method.
globSync: fs.globSync as NativeGlobSynchronous,
};
}

export function importPreviousFastGlob(): Promise<typeof previousVersion> {
return import('fast-glob');
}
Expand Down

0 comments on commit 22a5d5a

Please sign in to comment.