Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
aoeuaoeiaoei
(version: 0)
Comparing performance of:
createConstructor vs ClassUtils
Created:
5 years ago
by:
Guest
Jump to the latest result
Tests:
createConstructor
// utility functions for Immutability and Multiple Inheritance const createConstructor = function (funcArgs = {}) { const { classesToInherit, classProps, defaultArgs, methods } = funcArgs function deepFreeze(obj) { Object.getOwnPropertyNames(obj).map(key => { if (typeof obj[key] === 'object' && obj[key] !== null) deepFreeze(obj[key]) }) Object.freeze(obj) } // the passed constructor function InnerFunc (args = {}) { //set object props Object.assign(this, defaultArgs, args) //bind the methods per object const targetProto = Object.getPrototypeOf(this) Object.getOwnPropertyNames(targetProto).map(key => { if (key !== 'constructor') { Object.defineProperty(this, key, { enumerable: false, value: targetProto[key] instanceof Function ? targetProto[key].bind(this) : targetProto[key] }) } }) //freeze the object deepFreeze(this) } // set constructor props Object.assign(InnerFunc, classProps) // set inherited methods classesToInherit.map(constr => Object.getOwnPropertyNames(constr.prototype).map(key => { if (key !== 'constructor') { InnerFunc.prototype[key] = constr.prototype[key] } }) ) // set manually defined methods Object.assign(InnerFunc.prototype, methods) // method to copy object with some props changed InnerFunc.prototype.copyWithProps = function(props = {}) { return new this.constructor(Object.assign({}, this, props)) } // freeze the constructor deepFreeze(InnerFunc) return InnerFunc } // BADLY WRITTEN CLASSES class Height { constructor(args = {}) { this.height = args.height } getHeight() { return `Height: ${this.height}` } static heightInternal() { return 3 } } class Weight { constructor(args = {}) { this.weight = args.weight } getWeight() { return `Weight: ${this.weight}` } static weightInternal() { return 3 } } // WELL WRITTEN CLASSES const Person = createConstructor({ classesToInherit: [ Height, Weight ], classProps: { species: 'humans', internalMethod() { return 'Hello from inside the constructor' } }, defaultArgs: { name: 'John', age: 20, weight: 60, height: 160 }, methods: { // Uncomment to replace the inherited one //getHeight() { return 'CORRECT' }, // combines native with inherited methods greet() { console.log( `Hello, ${this.name}. ` + `${this.getWeight()}, ${this.getHeight()}` ) }, // calculates the method name first ['get' + 'Info']() { return `Name: ${this.name}, age: ${this.age}` }, // can also use async, * generator // which can also be static } }) for (let i = 0; i < 50; i++) { mark = new Person({ name: 'Mark', weight: 90, otherArg: true }) skinnyMark = mark.copyWithProps({ age: 32, weight: 75 }) skinnyMark.greet() mark.greet() }
ClassUtils
// utility functions for Immutability and Multiple Inheritance const ClassUtils = class Self { copyWithProps(props = {}) { return new this.constructor(Object.assign({}, this, props)) } finalizeInstance(props = {}) { if (!Object.isFrozen(this)) { //set object props Object.assign(this, props) //bind the methods per object const targetProto = Object.getPrototypeOf(this) Object.getOwnPropertyNames(targetProto).map(key => { if (key !== 'constructor') { Object.defineProperty(this, key, { enumerable: false, value: targetProto[key] instanceof Function ? targetProto[key].bind(this) : targetProto[key] }) } }) //freeze the object Self.deepFreeze(this) } } static deepFreeze(obj) { Object.getOwnPropertyNames(obj).map(key => { if (typeof obj[key] === 'object' && obj[key] !== null) Self.deepFreeze(obj[key]) }) Object.freeze(obj) } static finalizeClass({ target, props = {}, sources = [] }) { if (!Object.isFrozen(target)) { // set constructor props Object.assign(target, props) // set prototype methods sources.concat([Self, target]).map(constr => Object.getOwnPropertyNames(constr.prototype).map(key => { if (key !== 'constructor') { target.prototype[key] = constr.prototype[key] } }) ) // freeze the constructor Self.deepFreeze(target) } } } ClassUtils.deepFreeze(ClassUtils) // BADLY WRITTEN CLASSES class Height { constructor(args = {}) { this.height = args.height } getHeight() { return `Height: ${this.height}` } static heightInternal() { return 3 } } class Weight { constructor(args = {}) { this.weight = args.weight } getWeight() { return `Weight: ${this.weight}` } static weightInternal() { return 3 } } // WELL WRITTEN CLASSES const Person = class Self { constructor({ name, age, weight, height } = {}) { this.finalizeInstance({ name: name || 'John', age: age || 20, weight: weight || 60, height: height || 160 }) } // Uncomment to replace the inherited one //getHeight() { return 'CORRECT' } // combines native with inherited methods greet() { console.log(`Hello, ${this.name}. ${this.getWeight()}, ${this.getHeight()}`) } // calculates the method name first ['get' + 'Info']() { return `Name: ${this.name}, age: ${this.age}` } // class method static internalMethod() { return 'Hello from inside the constructor' } // can also use async, * generator // which can also be static } ClassUtils.finalizeClass({ target: Person, sources: [ Height, Weight ], props: { species: 'humans' } }) for (let i = 0; i < 50; i++) { mark = new Person({ name: 'Mark', weight: 90, otherArg: true }) skinnyMark = mark.copyWithProps({ age: 32, weight: 75 }) skinnyMark.greet() mark.greet() }
Rendered benchmark preparation results:
Suite status:
<idle, ready to run>
Run tests (2)
Previous results
Fork
Test case name
Result
createConstructor
ClassUtils
Fastest:
N/A
Slowest:
N/A
Latest run results:
No previous run results
This benchmark does not have any results yet. Be the first one
to run it!
Autogenerated LLM Summary
(model
llama3.2:3b
, generated one year ago):
A complex JavaScript class testing scenario! After analyzing the provided code, I'll provide a high-level overview of my findings: **Good practices:** 1. **Use of `finalizer`**: The `finalizeClass` method is used to ensure that certain properties and methods are properly set on the `Person` class. 2. **Proper inheritance**: The `Person` class uses a constructor with an object initializer, which sets up the instance's properties. 3. **Combining native and inherited methods**: The `greet()` method combines both native and inherited methods. **Improvement suggestions:** 1. **Naming conventions**: Some class names (e.g., `Height`, `Weight`) follow camelCase, while others (e.g., `Person`) follow PascalCase. It's essential to maintain consistency in naming conventions throughout the codebase. 2. **Code organization**: The provided code snippet is quite dense and mixes multiple concepts, such as constructor initialization, inheritance, and utility methods like `deepFreeze`. Consider breaking down the code into smaller, more focused modules or classes. 3. **Error handling**: There are no explicit error messages or handling mechanisms in place to catch and handle potential errors that might occur during class instantiation or method execution. **Performance optimization opportunities:** 1. **Minimize unnecessary computations**: The `heightInternal()` and `weightInternal()` methods, which return a hardcoded value, could be replaced with more efficient approaches, such as using getters or computed properties. 2. **Use caching**: If the `Height` and `Weight` classes are frequently instantiated, consider caching their internal values to avoid redundant calculations. **Security considerations:** 1. **Input validation**: The `Person` class's constructor accepts an object initializer with various properties (e.g., `name`, `age`, `weight`, `height`). Ensure that these properties are properly validated and sanitized to prevent potential security vulnerabilities, such as XSS attacks. By addressing these points, you can improve the maintainability, performance, and security of your JavaScript class testing codebase.
Related benchmarks:
Iterating over string
Class vs ID
matchAll vs exec
Array from vs string split with large strings
string comparisons 4
Comments
Confirm delete:
Do you really want to delete benchmark?