ronantakizawa/codereview-bench huggingface dataset:
Repository: toss/es-toolkit
File: src/compat/util/defaultTo.ts (TypeScript)

Code before:
/**
 * Checks value to determine whether a default value should be returned in its place.
 *
 * The defaultValue is returned if value is NaN, null, or undefined.
 *
 * @param {unknown} value - The value to check.
 * @param {unknown} defaultValue - The default value to return if the first value is null, undefined, or NaN.
 * @returns {unknown} Returns either the first value or the default value.
 *
 * @example
 * defaultTo(null, 'default') // returns 'default'
 * defaultTo(undefined, 42) // returns 42
 * defaultTo(NaN, 0) // returns 0
 * defaultTo('actual', 'default') // returns 'actual'
 * defaultTo(123, 0) // returns 123
 */
export function defaultTo(value?: unknown, defaultValue?: unknown): any {
  return value == null || Number.isNaN(value) ? defaultValue : value;
}


Review comment (suggestion):
```suggestion
  if (value == null || Number.isNaN(value)) {
    return defaultValue;
  }
  
  return value;
```

I guess `if` statements clearly shows the branches, so it might be more readable..

Code after:
/**
 * Checks value to determine whether a default value should be returned in its place.
 *
 * The defaultValue is returned if value is NaN, null, or undefined.
 *
 * @param {unknown} value - The value to check.
 * @param {unknown} defaultValue - The default value to return if the first value is null, undefined, or NaN.
 * @returns {unknown} Returns either the first value or the default value.
 *
 * @example
 * defaultTo(null, 'default') // returns 'default'
 * defaultTo(undefined, 42) // returns 42
 * defaultTo(NaN, 0) // returns 0
 * defaultTo('actual', 'default') // returns 'actual'
 * defaultTo(123, 0) // returns 123
 */
export function defaultTo(value?: unknown, defaultValue?: unknown): any {
  if (value == null || Number.isNaN(value)) {
    return defaultValue;
  }
  
  return value;
}
Repository: toss/es-toolkit
File: benchmarks/performance/dropRightWhile.bench.ts (TypeScript)

Code before:
import { bench, describe } from 'vitest';
import { dropRightWhile as dropRightWhileToolkit_ } from 'es-toolkit';
import { dropRightWhile as dropRightWhileLodash_ } from 'lodash';
import { dropRightWhile as dropRightWhileToolkitCompat_ } from '../../src/compat/array/dropRightWhile';

const dropRightWhileToolkit = dropRightWhileToolkit_;
const dropRightWhileToolkitCompat = dropRightWhileToolkitCompat_;
const dropRightWhileLodash = dropRightWhileLodash_;

describe('dropRightWhile', () => {
  bench('es-toolkit/dropRightWhile', () => {
    dropRightWhileToolkit([1.2, 2.3, 3.4], x => x < 2);
  });

  bench('es-toolkit (compat)/dropRightWhile', () => {
    dropRightWhileToolkitCompat([1.2, 2.3, 3.4], x => x < 2);
  });

  bench('lodash/dropRightWhile', () => {
    dropRightWhileLodash([1.2, 2.3, 3.4], x => x < 2);
  });
});

describe('dropRightWhile/largeArray', () => {
  const largeArray = Array.from({ length: 10000 }, (_, i) => i);

  bench('es-toolkit/dropRightWhile', () => {
    dropRightWhileToolkit(largeArray, x => x < 5000);
  });

Review comment (suggestion):
```suggestion
import { dropRightWhile as dropRightWhileToolkitCompat_ } from 'es-toolkit/compat';
```

Code after:
import { bench, describe } from 'vitest';
import { dropRightWhile as dropRightWhileToolkit_ } from 'es-toolkit';
import { dropRightWhile as dropRightWhileLodash_ } from 'lodash';
import { dropRightWhile as dropRightWhileToolkitCompat_ } from 'es-toolkit/compat';

const dropRightWhileToolkit = dropRightWhileToolkit_;
const dropRightWhileToolkitCompat = dropRightWhileToolkitCompat_;
const dropRightWhileLodash = dropRightWhileLodash_;

describe('dropRightWhile', () => {
  bench('es-toolkit/dropRightWhile', () => {
    dropRightWhileToolkit([1.2, 2.3, 3.4], x => x < 2);
  });

  bench('es-toolkit (compat)/dropRightWhile', () => {
    dropRightWhileToolkitCompat([1.2, 2.3, 3.4], x => x < 2);
  });

  bench('lodash/dropRightWhile', () => {
    dropRightWhileLodash([1.2, 2.3, 3.4], x => x < 2);
  });
});

describe('dropRightWhile/largeArray', () => {
  const largeArray = Array.from({ length: 10000 }, (_, i) => i);

  bench('es-toolkit/dropRightWhile', () => {
    dropRightWhileToolkit(largeArray, x => x < 5000);
  });
Repository: toss/es-toolkit
File: src/object/omitBy.ts (TypeScript)

Code before:
 *
 * This function takes an object and a predicate function, and returns a new object that
 * includes only the properties for which the predicate function returns false.
 *
 * @template T - The type of object.
 * @param {T} obj - The object to omit properties from.
 * @param {(value: T[string], key: keyof T) => boolean} shouldOmit - A predicate function that determines
 * whether a property should be omitted. It takes the property's key and value as arguments and returns `true`
 * if the property should be omitted, and `false` otherwise.
 * @returns {Partial<T>} A new object with the properties that do not satisfy the predicate function.
 *
 * @example
 * const obj = { a: 1, b: 'omit', c: 3 };
 * const shouldOmit = (value, key) => typeof value === 'string';
 * const result = omitBy(obj, shouldOmit);
 * // result will be { a: 1, c: 3 }
 */
export function omitBy<T extends Record<string, any>>(
  obj: T,
  shouldOmit: (value: T[keyof T], key: keyof T) => boolean
): Partial<T> {
  const result: Partial<T> = {};
  for (const key in obj) {
    const value = obj[key];
    if (!shouldOmit(value, key)) {
      result[key] = value;
    }
  }

  return result;
}


Review comment (suggestion):
Change `Object.entries` to `for...in`. 
This also improves the `any` type assertion.

Code after:
 *
 * This function takes an object and a predicate function, and returns a new object that
 * includes only the properties for which the predicate function returns false.
 *
 * @template T - The type of object.
 * @param {T} obj - The object to omit properties from.
 * @param {(value: T[string], key: keyof T) => boolean} shouldOmit - A predicate function that determines
 * whether a property should be omitted. It takes the property's key and value as arguments and returns `true`
 * if the property should be omitted, and `false` otherwise.
 * @returns {Partial<T>} A new object with the properties that do not satisfy the predicate function.
 *
 * @example
 * const obj = { a: 1, b: 'omit', c: 3 };
 * const shouldOmit = (value) => typeof value === 'string';
 * const result = omitBy(obj, shouldOmit);
 * // result will be { a: 1, c: 3 }
 */
export function omitBy<T extends Record<string, any>>(
  obj: T,
  shouldOmit: (value: T[keyof T], key: keyof T) => boolean
): Partial<T> {
  const result: Partial<T> = {};

  const keys = Object.keys(obj);
  
  for (let i = 0; i < keys.length; i++) {
    const key = keys[i];
    const value = obj[key];
    if (!shouldOmit(value, key)) {
      (result as any)[key] = value;
    }
  }

  return result;
}
Repository: toss/es-toolkit
File: src/object/omitBy.ts (TypeScript)

Code before:
/**
 * Creates a new object composed of the properties that do not satisfy the predicate function.
 *
 * This function takes an object and a predicate function, and returns a new object that
 * includes only the properties for which the predicate function returns false.
 *
 * @template T - The type of object.
 * @param {T} obj - The object to omit properties from.
 * @param {(value: T[string], key: keyof T) => boolean} shouldOmit - A predicate function that determines
 * whether a property should be omitted. It takes the property's key and value as arguments and returns `true`
 * if the property should be omitted, and `false` otherwise.
 * @returns {Partial<T>} A new object with the properties that do not satisfy the predicate function.
 *
 * @example
 * const obj = { a: 1, b: 'omit', c: 3 };
 * const shouldOmit = (value) => typeof value === 'string';
 * const result = omitBy(obj, shouldOmit);
 * // result will be { a: 1, c: 3 }
 */
export function omitBy<T extends Record<string, any>>(
  obj: T,
  shouldOmit: (value: T[keyof T], key: keyof T) => boolean
): Partial<T> {
  const result: Partial<T> = {};
  for (const key in obj) {
    const value = obj[key];
    if (!shouldOmit(value, key)) {
      result[key] = value;
    }
  }

  return result;
}


Review comment (performance):
Actually, `Object.entries(...)` returns only the object's own properties, while the `for ... in` loop includes all inherited properties. This is an important difference. 

Also, is there a performance difference if we use `Object.keys(...)` in this context? If it's more performant, we might use `Object.keys(...)` here.


Code after:
/**
 * Creates a new object composed of the properties that do not satisfy the predicate function.
 *
 * This function takes an object and a predicate function, and returns a new object that
 * includes only the properties for which the predicate function returns false.
 *
 * @template T - The type of object.
 * @param {T} obj - The object to omit properties from.
 * @param {(value: T[string], key: keyof T) => boolean} shouldOmit - A predicate function that determines
 * whether a property should be omitted. It takes the property's key and value as arguments and returns `true`
 * if the property should be omitted, and `false` otherwise.
 * @returns {Partial<T>} A new object with the properties that do not satisfy the predicate function.
 *
 * @example
 * const obj = { a: 1, b: 'omit', c: 3 };
 * const shouldOmit = (value) => typeof value === 'string';
 * const result = omitBy(obj, shouldOmit);
 * // result will be { a: 1, c: 3 }
 */
export function omitBy<T extends Record<string, any>>(
  obj: T,
  shouldOmit: (value: T[keyof T], key: keyof T) => boolean
): Partial<T> {
  const result: Partial<T> = {};

  const keys = Object.keys(obj);
  
  for (let i = 0; i < keys.length; i++) {
    const key = keys[i];
    const value = obj[key];
    if (!shouldOmit(value, key)) {
      (result as any)[key] = value;
    }
  }

  return result;
}
Repository: toss/es-toolkit
File: src/object/omitBy.ts (TypeScript)

Code before:
 * This function takes an object and a predicate function, and returns a new object that
 * includes only the properties for which the predicate function returns false.
 *
 * @template T - The type of object.
 * @param {T} obj - The object to omit properties from.
 * @param {(value: T[string], key: keyof T) => boolean} shouldOmit - A predicate function that determines
 * whether a property should be omitted. It takes the property's key and value as arguments and returns `true`
 * if the property should be omitted, and `false` otherwise.
 * @returns {Partial<T>} A new object with the properties that do not satisfy the predicate function.
 *
 * @example
 * const obj = { a: 1, b: 'omit', c: 3 };
 * const shouldOmit = (value) => typeof value === 'string';
 * const result = omitBy(obj, shouldOmit);
 * // result will be { a: 1, c: 3 }
 */
export function omitBy<T extends Record<string, any>>(
  obj: T,
  shouldOmit: (value: T[keyof T], key: keyof T) => boolean
): Partial<T> {
  const result: Partial<T> = {};

  const objectKeys = Object.keys(obj);
  for (let i = 0; i < objectKeys.length; i++) {
    const key = objectKeys[i];
    const value = obj[key];
    if (!shouldOmit(value, key)) {
      (result as any)[key] = value;
    }
  }

  return result;
}


Review comment (suggestion):
```suggestion
  const keys = Object.keys(obj);
  
  for (let i = 0; i < keys.length; i++) {
    const key = keys[i];
    const value = obj[key];
```

Code after:
 * This function takes an object and a predicate function, and returns a new object that
 * includes only the properties for which the predicate function returns false.
 *
 * @template T - The type of object.
 * @param {T} obj - The object to omit properties from.
 * @param {(value: T[string], key: keyof T) => boolean} shouldOmit - A predicate function that determines
 * whether a property should be omitted. It takes the property's key and value as arguments and returns `true`
 * if the property should be omitted, and `false` otherwise.
 * @returns {Partial<T>} A new object with the properties that do not satisfy the predicate function.
 *
 * @example
 * const obj = { a: 1, b: 'omit', c: 3 };
 * const shouldOmit = (value) => typeof value === 'string';
 * const result = omitBy(obj, shouldOmit);
 * // result will be { a: 1, c: 3 }
 */
export function omitBy<T extends Record<string, any>>(
  obj: T,
  shouldOmit: (value: T[keyof T], key: keyof T) => boolean
): Partial<T> {
  const result: Partial<T> = {};

  const keys = Object.keys(obj);
  
  for (let i = 0; i < keys.length; i++) {
    const key = keys[i];
    const value = obj[key];
    if (!shouldOmit(value, key)) {
      (result as any)[key] = value;
    }
  }

  return result;
}
Repository: toss/es-toolkit
File: src/array/unionBy.ts (TypeScript)

Code before:
import { uniqBy } from './uniqBy';

/**
 * Creates an array of unique values, in order, from all given arrays using a provided mapping function to determine equality.
 *
 * @template T - The type of elements in the array.
 * @template U - The type of mapped elements.
 * @param {T[]} arr1 - The first array.
 * @param {T[]} arr2 - The second array.
 * @param {(item: T) => U} mapper - The function to map array elements to comparison values.
 * @returns {T[]} A new array containing the union of unique elements from `arr1` and `arr2`, based on the values returned by the mapping function.
 *
 * @example
 * // Custom mapping function for numbers (modulo comparison)
 * const moduloMapper = (x) => x % 3;
 * unionBy([1, 2, 3], [4, 5, 6], moduloMapper);
 * // Returns [1, 2, 3]
 *
 * @example
 * // Custom mapping function for objects with an 'id' property
 * const idMapper = (obj) => obj.id;
 * unionBy([{ id: 1 }, { id: 2 }], [{ id: 2 }, { id: 3 }], idMapper);
 * // Returns [{ id: 1 }, { id: 2 }, { id: 3 }]
 */
export function unionBy<T, U>(arr1: readonly T[], arr2: readonly T[], mapper: (item: T) => U): T[] {
  return uniqBy(arr1.concat(arr2), mapper);

Review comment (suggestion):
```suggestion
import { uniqBy } from './uniqBy.ts';
```

Code after:
import { uniqBy } from './uniqBy.ts';

/**
 * Creates an array of unique values, in order, from all given arrays using a provided mapping function to determine equality.
 *
 * @template T - The type of elements in the array.
 * @template U - The type of mapped elements.
 * @param {T[]} arr1 - The first array.
 * @param {T[]} arr2 - The second array.
 * @param {(item: T) => U} mapper - The function to map array elements to comparison values.
 * @returns {T[]} A new array containing the union of unique elements from `arr1` and `arr2`, based on the values returned by the mapping function.
 *
 * @example
 * // Custom mapping function for numbers (modulo comparison)
 * const moduloMapper = (x) => x % 3;
 * unionBy([1, 2, 3], [4, 5, 6], moduloMapper);
 * // Returns [1, 2, 3]
 *
 * @example
 * // Custom mapping function for objects with an 'id' property
 * const idMapper = (obj) => obj.id;
 * unionBy([{ id: 1 }, { id: 2 }], [{ id: 2 }, { id: 3 }], idMapper);
 * // Returns [{ id: 1 }, { id: 2 }, { id: 3 }]
 */
export function unionBy<T, U>(arr1: readonly T[], arr2: readonly T[], mapper: (item: T) => U): T[] {
  return uniqBy(arr1.concat(arr2), mapper);
Repository: toss/es-toolkit
File: benchmarks/performance/intersection.bench.ts (TypeScript)

Code before:
import { bench, describe } from 'vitest';
import { intersection as intersectionToolkit_ } from 'es-toolkit';
import { intersection as intersectionCompatToolkit_ } from 'es-toolkit/compat';
import { intersection as intersectionLodash_ } from 'lodash';

const intersectionToolkit = intersectionToolkit_;
const intersectionCompatToolkit = intersectionCompatToolkit_;
const intersectionLodash = intersectionLodash_;

describe('intersection, small arrays', () => {
  const array1 = [1, 2, 3];
  const array2 = [2, 4];

  bench('es-toolkit/intersection', () => {
    intersectionToolkit(array1, array2);
  });

  bench('es-toolkit/compat/difference', () => {
    intersectionCompatToolkit([1, 2, 3], [2]);
  });

  bench('lodash/intersection', () => {
    intersectionLodash(array1, array2);
  });
});

describe('intersection, large arrays', () => {
  const array1 = Array.from({ length: 10000 }, () => Math.floor(Math.random() * 1000));
  const array2 = Array.from({ length: 10000 }, () => Math.floor(Math.random() * 1000));

  bench('es-toolkit/intersection', () => {
    intersectionToolkit(array1, array2);
  });

  bench('es-toolkit/compat/difference', () => {
    intersectionCompatToolkit(array1, array2);
  });

  bench('lodash/intersection', () => {
    intersectionLodash(array1, array2);
  });
});


Review comment (suggestion):
```suggestion
  bench('es-toolkit/compat/intersection', () => {
```

Code after:
import { bench, describe } from 'vitest';
import { intersection as intersectionToolkit_ } from 'es-toolkit';
import { intersection as intersectionCompatToolkit_ } from 'es-toolkit/compat';
import { intersection as intersectionLodash_ } from 'lodash';

const intersectionToolkit = intersectionToolkit_;
const intersectionCompatToolkit = intersectionCompatToolkit_;
const intersectionLodash = intersectionLodash_;

describe('intersection, small arrays', () => {
  const array1 = [1, 2, 3];
  const array2 = [2, 4];

  bench('es-toolkit/intersection', () => {
    intersectionToolkit(array1, array2);
  });

  bench('es-toolkit/compat/intersection', () => {
    intersectionCompatToolkit([1, 2, 3], [2]);
  });

  bench('lodash/intersection', () => {
    intersectionLodash(array1, array2);
  });
});

describe('intersection, large arrays', () => {
  const array1 = Array.from({ length: 10000 }, () => Math.floor(Math.random() * 1000));
  const array2 = Array.from({ length: 10000 }, () => Math.floor(Math.random() * 1000));

  bench('es-toolkit/intersection', () => {
    intersectionToolkit(array1, array2);
  });

  bench('es-toolkit/compat/intersection', () => {
    intersectionCompatToolkit(array1, array2);
  });

  bench('lodash/intersection', () => {
    intersectionLodash(array1, array2);
  });
});
Repository: toss/es-toolkit
File: benchmarks/performance/intersection.bench.ts (TypeScript)

Code before:
describe('intersection, small arrays', () => {
  const array1 = [1, 2, 3];
  const array2 = [2, 4];

  bench('es-toolkit/intersection', () => {
    intersectionToolkit(array1, array2);
  });

  bench('es-toolkit/compat/difference', () => {
    intersectionCompatToolkit([1, 2, 3], [2]);
  });

  bench('lodash/intersection', () => {
    intersectionLodash(array1, array2);
  });
});

describe('intersection, large arrays', () => {
  const array1 = Array.from({ length: 10000 }, () => Math.floor(Math.random() * 1000));
  const array2 = Array.from({ length: 10000 }, () => Math.floor(Math.random() * 1000));

  bench('es-toolkit/intersection', () => {
    intersectionToolkit(array1, array2);
  });

  bench('es-toolkit/compat/difference', () => {
    intersectionCompatToolkit(array1, array2);
  });

  bench('lodash/intersection', () => {
    intersectionLodash(array1, array2);
  });
});


Review comment (suggestion):
```suggestion
  bench('es-toolkit/compat/intersection', () => {
```

Code after:
describe('intersection, small arrays', () => {
  const array1 = [1, 2, 3];
  const array2 = [2, 4];

  bench('es-toolkit/intersection', () => {
    intersectionToolkit(array1, array2);
  });

  bench('es-toolkit/compat/intersection', () => {
    intersectionCompatToolkit([1, 2, 3], [2]);
  });

  bench('lodash/intersection', () => {
    intersectionLodash(array1, array2);
  });
});

describe('intersection, large arrays', () => {
  const array1 = Array.from({ length: 10000 }, () => Math.floor(Math.random() * 1000));
  const array2 = Array.from({ length: 10000 }, () => Math.floor(Math.random() * 1000));

  bench('es-toolkit/intersection', () => {
    intersectionToolkit(array1, array2);
  });

  bench('es-toolkit/compat/intersection', () => {
    intersectionCompatToolkit(array1, array2);
  });

  bench('lodash/intersection', () => {
    intersectionLodash(array1, array2);
  });
});
Repository: toss/es-toolkit
File: src/compat/array/intersection.spec.ts (TypeScript)

Code before:

    const actual = values.map(value => {
      const largeArray = times(LARGE_ARRAY_SIZE, constant(value));
      return intersection(values, largeArray).map(toString);
    });

    expect(actual).toEqual(expected);
  });

  it('should work with large arrays of `NaN`', () => {
    const largeArray = times(LARGE_ARRAY_SIZE, stubNaN);
    expect(intersection([1, NaN, 3], largeArray)).toEqual([NaN]);
  });

  it('should work with large arrays of objects', () => {
    const object = {};
    const largeArray = times(LARGE_ARRAY_SIZE, constant(object));

    expect(intersection([object], largeArray)).toEqual([object]);
    expect(intersection(range(LARGE_ARRAY_SIZE), [1])).toEqual([1]);
  });

  it('should treat values that are not arrays or `arguments` objects as empty', () => {
    const array = [0, 1, null, 3];
    expect(intersection(array, 3, { 0: 1 }, null)).toEqual([]);
    expect(intersection(null, array, null, [2, 3])).toEqual([]);
    expect(intersection(array, null, args, null)).toEqual([]);
  });
});


Review comment (suggestion):
```suggestion
    // @ts-ignore
    expect(intersection(array, 3, { 0: 1 }, null)).toEqual([]);
```

Code after:

    const actual = values.map(value => {
      const largeArray = times(LARGE_ARRAY_SIZE, constant(value));
      return intersection(values, largeArray).map(toString);
    });

    expect(actual).toEqual(expected);
  });

  it('should work with large arrays of `NaN`', () => {
    const largeArray = times(LARGE_ARRAY_SIZE, stubNaN);
    expect(intersection([1, NaN, 3], largeArray)).toEqual([NaN]);
  });

  it('should work with large arrays of objects', () => {
    const object = {};
    const largeArray = times(LARGE_ARRAY_SIZE, constant(object));

    expect(intersection([object], largeArray)).toEqual([object]);
    expect(intersection(range(LARGE_ARRAY_SIZE), [1])).toEqual([1]);
  });

  it('should treat values that are not arrays or `arguments` objects as empty', () => {
    const array = [0, 1, null, 3];
    // @ts-ignore
    expect(intersection(array, 3, { 0: 1 }, null)).toEqual([]);
    expect(intersection(null, array, null, [2, 3])).toEqual([]);
    expect(intersection(array, null, args, null)).toEqual([]);
  });
});