Skip to content

Commit 6c46cc2

Browse files
committed
feat: added performance test for 2618
1 parent 26beaf3 commit 6c46cc2

File tree

5 files changed

+96
-40
lines changed

5 files changed

+96
-40
lines changed

prettier.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export default {
22
singleQuote: true,
33
trailingComma: 'all',
44
tabWidth: 2,
5-
semi: false,
5+
semi: true,
66
printWidth: 100,
77
bracketSpacing: true,
88
arrowParens: 'avoid',

src/__tests__/2618-check-if-object-instance-of-class.test.ts

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import {
22
checkIfInstanceOf,
33
checkIfInstanceOfUsingPrototype,
4-
} from '@/app/2618-check-if-object-instance-of-class'
4+
InstanceOfFunction,
5+
} from '@/app/2618-check-if-object-instance-of-class';
56

67
describe('Problem 2618: Check If Instance Of Class', () => {
78
const testCases: {
8-
name: string
9-
input: [any, any]
10-
expected: boolean
9+
name: string;
10+
input: [any, any];
11+
expected: boolean;
1112
}[] = [
1213
{
1314
name: 'Example 1: new Date() is an instance of Date',
@@ -19,7 +20,7 @@ describe('Problem 2618: Check If Instance Of Class', () => {
1920
input: (() => {
2021
class Animal {}
2122
class Dog extends Animal {}
22-
return [new Dog(), Animal] as [any, any]
23+
return [new Dog(), Animal] as [any, any];
2324
})(),
2425
expected: true,
2526
},
@@ -43,16 +44,69 @@ describe('Problem 2618: Check If Instance Of Class', () => {
4344
input: [new Number(5), undefined],
4445
expected: false,
4546
},
46-
]
47+
];
4748

49+
// ✅ Correctness Tests
4850
describe.each([
4951
['🔍 instanceof version', checkIfInstanceOf],
5052
['🔁 prototype-traversal version', checkIfInstanceOfUsingPrototype],
51-
])('%s', (_label, fn) => {
53+
])('%s - Correctness', (_label, fn) => {
5254
testCases.forEach(({ name, input, expected }) => {
5355
test(name, () => {
54-
expect(fn(...input)).toBe(expected)
55-
})
56-
})
57-
})
58-
})
56+
expect(fn(...input)).toBe(expected);
57+
});
58+
});
59+
});
60+
61+
// ✅ Dynamic Fuzzing
62+
describe.each([
63+
['🔍 instanceof version', checkIfInstanceOf],
64+
['🔁 prototype-traversal version', checkIfInstanceOfUsingPrototype],
65+
])('%s - Dynamic Fuzzing', (_label, fn) => {
66+
const constructors = [
67+
Date,
68+
Number,
69+
String,
70+
Boolean,
71+
Object,
72+
Array,
73+
Map,
74+
Set,
75+
WeakMap,
76+
WeakSet,
77+
RegExp,
78+
Error,
79+
];
80+
81+
test('Run 500 random fuzzing tests', () => {
82+
for (let i = 0; i < 500; i++) {
83+
const randomClass = constructors[Math.floor(Math.random() * constructors.length)];
84+
const instance = new (randomClass as any)();
85+
const expected = instance instanceof randomClass;
86+
const result = fn(instance, randomClass);
87+
expect(result).toBe(expected);
88+
}
89+
});
90+
});
91+
92+
// ✅ Benchmarking
93+
describe('🚀 Benchmarking Performance', () => {
94+
const iterations = 100_000;
95+
const Dog = class extends Object {};
96+
const input: [any, any] = [new Dog(), Object];
97+
98+
const benchmark = (label: string, fn: InstanceOfFunction) => {
99+
const start = performance.now();
100+
for (let i = 0; i < iterations; i++) {
101+
fn(...input);
102+
}
103+
const end = performance.now();
104+
console.log(`${label} took ${(end - start).toFixed(2)}ms for ${iterations} iterations`);
105+
};
106+
107+
test('Compare performance', () => {
108+
benchmark('checkIfInstanceOf', checkIfInstanceOf);
109+
benchmark('checkIfInstanceOfUsingPrototype', checkIfInstanceOfUsingPrototype);
110+
});
111+
});
112+
});

src/app/2618-check-if-object-instance-of-class.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,53 +28,55 @@
2828
// https://leetcode.com/problems/check-if-object-instance-of-class/description
2929

3030
// * Solution
31+
export type InstanceOfFunction = (obj: any, classFunction: any) => boolean;
32+
3133
function checkIfInstanceOf(obj: any, classFunction: any): boolean {
3234
// If obj is null or undefined, it can't be an instance of anything
33-
if (obj === null || obj === undefined) return false
35+
if (obj === null || obj === undefined) return false;
3436

3537
// If classFunction is not a function (i.e., not a constructor), return false
36-
if (typeof classFunction !== 'function') return false
38+
if (typeof classFunction !== 'function') return false;
3739

3840
// If the object is already an instance of the class, return true
39-
if (obj instanceof classFunction) return true
41+
if (obj instanceof classFunction) return true;
4042

4143
// Try converting the value to an object and check again using instanceof
4244
// This handles edge cases like primitives (e.g., number, string)
4345
try {
44-
return Object(obj) instanceof classFunction
46+
return Object(obj) instanceof classFunction;
4547
} catch {
4648
// If conversion or check fails (e.g., invalid input), return false
47-
return false
49+
return false;
4850
}
4951
}
5052

5153
function checkIfInstanceOfUsingPrototype(obj: any, classFunction: any): boolean {
5254
// Return false if the input value is null or undefined
53-
if (obj === null || obj === undefined) return false
55+
if (obj === null || obj === undefined) return false;
5456

5557
// Return false if the classFunction is not a function (constructor)
56-
if (typeof classFunction !== 'function') return false
58+
if (typeof classFunction !== 'function') return false;
5759

5860
// Get the prototype that we're trying to match
59-
const targetPrototype = classFunction.prototype
61+
const targetPrototype = classFunction.prototype;
6062

6163
// Convert obj to an object (handles primitives like numbers, strings, etc.)
62-
let currentProto = Object(obj)
64+
let currentProto = Object(obj);
6365

6466
// Traverse up the prototype chain
6567
while (currentProto !== null) {
6668
// If the prototype matches the target, return true
6769
if (Object.getPrototypeOf(currentProto) === targetPrototype) {
68-
return true
70+
return true;
6971
}
7072

7173
// Move one level up the prototype chain
72-
currentProto = Object.getPrototypeOf(currentProto)
74+
currentProto = Object.getPrototypeOf(currentProto);
7375
}
7476

7577
// If we reach the end of the chain without a match, return false
76-
return false
78+
return false;
7779
}
7880

7981
// * Export the function
80-
export { checkIfInstanceOf, checkIfInstanceOfUsingPrototype }
82+
export { checkIfInstanceOf, checkIfInstanceOfUsingPrototype };

src/main.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import chalk from 'chalk'
1+
import chalk from 'chalk';
22

33
function main() {
4-
console.clear()
4+
console.clear();
55
console.log(
66
chalk.green.bold('\n🚀 Welcome to ') + chalk.blueBright.bold('LeetCode JavaScript Practice!\n'),
7-
)
7+
);
88

99
console.log(
1010
chalk.gray('📚 This is a curated collection of LeetCode problems with:') +
@@ -14,17 +14,17 @@ function main() {
1414
chalk.cyan(' • Clear explanations') +
1515
'\n' +
1616
chalk.cyan(' • Concept-based tagging for deep learning\n'),
17-
)
17+
);
1818

1919
console.log(
2020
chalk.yellow('✨ Run ') +
2121
chalk.magenta('pnpm test') +
2222
chalk.yellow(' to test all problems or ') +
2323
chalk.magenta('pnpm test:problem') +
2424
chalk.yellow(' to run a specific one.\n'),
25-
)
25+
);
2626

27-
console.log(chalk.green('Happy coding! 💻\n'))
27+
console.log(chalk.green('Happy coding! 💻\n'));
2828
}
2929

30-
main()
30+
main();

src/scripts/test-problem.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import { execSync } from 'child_process'
1+
import { execSync } from 'child_process';
22

3-
const problemNumber = process.argv[2]
3+
const problemNumber = process.argv[2];
44

55
if (!problemNumber) {
6-
console.error('❌ Please provide a problem number (e.g. 2618)')
7-
process.exit(1)
6+
console.error('❌ Please provide a problem number (e.g. 2618)');
7+
process.exit(1);
88
}
99

1010
try {
11-
execSync(`pnpm jest --testPathPatterns=${problemNumber}`, { stdio: 'inherit' })
11+
execSync(`pnpm jest --testPathPatterns=${problemNumber}`, { stdio: 'inherit' });
1212
} catch (err) {
13-
console.error('❌ Test run failed.', err)
14-
process.exit(1)
13+
console.error('❌ Test run failed.', err);
14+
process.exit(1);
1515
}

0 commit comments

Comments
 (0)