From 1e2013df5e03b576028559cd44891055370c21ec Mon Sep 17 00:00:00 2001 From: Revone Date: Mon, 20 Nov 2023 09:51:34 +0800 Subject: [PATCH] refactor: Eliminate unnecessary data structures. test: Add performance comparison tests with native Map and Set. --- CHANGELOG.md | 2 +- src/data-structures/hash/coordinate-map.ts | 63 --------------- src/data-structures/hash/coordinate-set.ts | 52 ------------- src/data-structures/hash/index.ts | 4 - src/data-structures/hash/tree-map.ts | 2 - src/data-structures/hash/tree-set.ts | 2 - .../hash/coordinate-map.test.ts | 0 .../hash/coordinate-set.test.ts | 0 .../data-structures/hash/hash-map.test.ts | 76 +++++++++++++++++++ .../hash/coordinate-map.test.ts | 74 ------------------ .../hash/coordinate-set.test.ts | 66 ---------------- .../data-structures/hash/hash-map.test.ts | 32 ++++++++ 12 files changed, 109 insertions(+), 264 deletions(-) delete mode 100644 src/data-structures/hash/coordinate-map.ts delete mode 100644 src/data-structures/hash/coordinate-set.ts delete mode 100644 src/data-structures/hash/tree-map.ts delete mode 100644 src/data-structures/hash/tree-set.ts delete mode 100644 test/performance/data-structures/hash/coordinate-map.test.ts delete mode 100644 test/performance/data-structures/hash/coordinate-set.test.ts delete mode 100644 test/unit/data-structures/hash/coordinate-map.test.ts delete mode 100644 test/unit/data-structures/hash/coordinate-set.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index ce0dd2f..82e5ebe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. - [Semantic Versioning](https://semver.org/spec/v2.0.0.html) - [`auto-changelog`](https://github.com/CookPete/auto-changelog) -## [v1.46.2](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming) +## [v1.46.3](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming) ### Changes diff --git a/src/data-structures/hash/coordinate-map.ts b/src/data-structures/hash/coordinate-map.ts deleted file mode 100644 index 02ffd45..0000000 --- a/src/data-structures/hash/coordinate-map.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * data-structure-typed - * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng - * @license MIT License - */ -export class CoordinateMap extends Map { - constructor(joint?: string) { - super(); - if (joint !== undefined) this._joint = joint; - } - - protected _joint = '_'; - - get joint(): string { - return this._joint; - } - - /** - * The "has" function overrides the base class's "has" function and checks if a key exists in the map by joining the - * key array with a specified delimiter. - * @param {number[]} key - The parameter "key" is an array of numbers. - * @returns The `has` method is being overridden to return the result of calling the `has` method of the superclass - * (`super.has`) with the `key` array joined together using the `_joint` property. - */ - override has(key: number[]) { - return super.has(key.join(this._joint)); - } - - /** - * The function overrides the set method of a Map object to convert the key from an array to a string using a specified - * delimiter before calling the original set method. - * @param {number[]} key - The key parameter is an array of numbers. - * @param {V} value - The value parameter is the value that you want to associate with the specified key. - * @returns The `set` method is returning the result of calling the `set` method of the superclass - * (`super.set(key.join(this._joint), value)`). - */ - override set(key: number[], value: V) { - return super.set(key.join(this._joint), value); - } - - /** - * The function overrides the get method to join the key array with a specified joint and then calls the super get - * method. - * @param {number[]} key - An array of numbers - * @returns The code is returning the value associated with the specified key in the map. - */ - override get(key: number[]) { - return super.get(key.join(this._joint)); - } - - /** - * The function overrides the delete method and joins the key array using a specified joint character before calling - * the super delete method. - * @param {number[]} key - An array of numbers that represents the key to be deleted. - * @returns The `delete` method is returning the result of calling the `delete` method on the superclass, with the - * `key` array joined together using the `_joint` property. - */ - override delete(key: number[]) { - return super.delete(key.join(this._joint)); - } -} diff --git a/src/data-structures/hash/coordinate-set.ts b/src/data-structures/hash/coordinate-set.ts deleted file mode 100644 index e7437eb..0000000 --- a/src/data-structures/hash/coordinate-set.ts +++ /dev/null @@ -1,52 +0,0 @@ -/** - * data-structure-typed - * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng - * @license MIT License - */ -export class CoordinateSet extends Set { - constructor(joint?: string) { - super(); - if (joint !== undefined) this._joint = joint; - } - - protected _joint = '_'; - - get joint(): string { - return this._joint; - } - - /** - * The "has" function overrides the "has" method of the superclass and checks if a value exists in an array after - * joining its elements with a specified separator. - * @param {number[]} value - The parameter "value" is an array of numbers. - * @returns The overridden `has` method is returning the result of calling the `has` method of the superclass, passing - * in the joined value as an argument. - */ - override has(value: number[]) { - return super.has(value.join(this._joint)); - } - - /** - * The "add" function overrides the parent class's "add" function by joining the elements of the input array with a - * specified delimiter before calling the parent class's "add" function. - * @param {number[]} value - An array of numbers - * @returns The overridden `add` method is returning the result of calling the `add` method of the superclass - * (`super.add`) with the joined string representation of the `value` array (`value.join(this._joint)`). - */ - override add(value: number[]) { - return super.add(value.join(this._joint)); - } - - /** - * The function overrides the delete method and deletes an element from a Set by joining the elements of the input - * array with a specified joint and then calling the delete method of the parent class. - * @param {number[]} value - An array of numbers - * @returns The `delete` method is returning the result of calling the `delete` method of the superclass, with the - * `value` array joined together using the `_joint` property. - */ - override delete(value: number[]) { - return super.delete(value.join(this._joint)); - } -} diff --git a/src/data-structures/hash/index.ts b/src/data-structures/hash/index.ts index 728fd5f..5d7849d 100644 --- a/src/data-structures/hash/index.ts +++ b/src/data-structures/hash/index.ts @@ -1,6 +1,2 @@ export * from './hash-table'; -export * from './coordinate-map'; -export * from './coordinate-set'; -export * from './tree-map'; -export * from './tree-set'; export * from './hash-map'; diff --git a/src/data-structures/hash/tree-map.ts b/src/data-structures/hash/tree-map.ts deleted file mode 100644 index a6d743d..0000000 --- a/src/data-structures/hash/tree-map.ts +++ /dev/null @@ -1,2 +0,0 @@ -export class TreeMap { -} diff --git a/src/data-structures/hash/tree-set.ts b/src/data-structures/hash/tree-set.ts deleted file mode 100644 index 65f14db..0000000 --- a/src/data-structures/hash/tree-set.ts +++ /dev/null @@ -1,2 +0,0 @@ -export class TreeSet { -} diff --git a/test/performance/data-structures/hash/coordinate-map.test.ts b/test/performance/data-structures/hash/coordinate-map.test.ts deleted file mode 100644 index e69de29..0000000 diff --git a/test/performance/data-structures/hash/coordinate-set.test.ts b/test/performance/data-structures/hash/coordinate-set.test.ts deleted file mode 100644 index e69de29..0000000 diff --git a/test/performance/data-structures/hash/hash-map.test.ts b/test/performance/data-structures/hash/hash-map.test.ts index a48c842..38ef805 100644 --- a/test/performance/data-structures/hash/hash-map.test.ts +++ b/test/performance/data-structures/hash/hash-map.test.ts @@ -23,6 +23,7 @@ if (isCompetitor) { } }); } + suite.add(`${MILLION.toLocaleString()} set & get`, () => { const hm = new HashMap(); @@ -33,6 +34,41 @@ suite.add(`${MILLION.toLocaleString()} set & get`, () => { hm.get(i); } }); + +suite.add(`${MILLION.toLocaleString()} Map set & get`, () => { + const hm = new Map(); + + for (let i = 0; i < MILLION; i++) { + hm.set(i, i); + } + for (let i = 0; i < MILLION; i++) { + hm.get(i); + } +}); + +suite.add(`${MILLION.toLocaleString()} Map set`, () => { + const hm = new Map(); + + for (let i = 0; i < MILLION; i++) hm.set(i, i); +}); + +suite.add(`${MILLION.toLocaleString()} Set add`, () => { + const hs = new Set(); + + for (let i = 0; i < MILLION; i++) hs.add(i); +}); + +suite.add(`${MILLION.toLocaleString()} Set add & has`, () => { + const hs = new Set(); + + for (let i = 0; i < MILLION; i++) { + hs.add(i); + } + for (let i = 0; i < MILLION; i++) { + hs.has(i); + } +}); + if (isCompetitor) { suite.add(`${MILLION.toLocaleString()} CPT set & get`, () => { const hm = new CHashMap(); @@ -45,4 +81,44 @@ if (isCompetitor) { } }); } + +suite.add(`${MILLION.toLocaleString()} ObjKey set & get`, () => { + const hm = new HashMap<[number, number], number>(); + const objKeys:[number, number][] = []; + for (let i = 0; i < MILLION; i++) { + const obj: [number, number] = [i, i]; + objKeys.push(obj) + hm.set(obj, i); + } + for (let i = 0; i < MILLION; i++) { + hm.get(objKeys[i]); + } +}); + +suite.add(`${MILLION.toLocaleString()} Map ObjKey set & get`, () => { + const hm = new Map<[number, number], number>(); + const objs:[number, number][] = []; + for (let i = 0; i < MILLION; i++) { + const obj: [number, number] = [i, i]; + objs.push(obj) + hm.set(obj, i); + } + for (let i = 0; i < MILLION; i++) { + hm.get(objs[i]); + } +}); + +suite.add(`${MILLION.toLocaleString()} Set ObjKey add & has`, () => { + const hs = new Set<[number, number]>(); + const objs:[number, number][] = []; + for (let i = 0; i < MILLION; i++) { + const obj: [number, number] = [i, i]; + objs.push(obj) + hs.add(obj); + } + for (let i = 0; i < MILLION; i++) { + hs.has(objs[i]); + } +}); + export { suite }; diff --git a/test/unit/data-structures/hash/coordinate-map.test.ts b/test/unit/data-structures/hash/coordinate-map.test.ts deleted file mode 100644 index 30536fd..0000000 --- a/test/unit/data-structures/hash/coordinate-map.test.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { CoordinateMap } from '../../../../src'; - -describe('CoordinateMap', () => { - it('should set and get values correctly', () => { - const coordinateMap = new CoordinateMap(); - const key = [1, 2, 3]; - const value = 'TestValue'; - - coordinateMap.set(key, value); - const retrievedValue = coordinateMap.get(key); - - expect(retrievedValue).toBe(value); - }); - - it('should return true when key exists', () => { - const coordinateMap = new CoordinateMap(); - const key = [1, 2, 3]; - const value = 'TestValue'; - - coordinateMap.set(key, value); - - expect(coordinateMap.has(key)).toBe(true); - }); - - it('should return false when key does not exist', () => { - const coordinateMap = new CoordinateMap(); - const key = [1, 2, 3]; - - expect(coordinateMap.has(key)).toBe(false); - }); - - it('should delete key-value pair correctly', () => { - const coordinateMap = new CoordinateMap(); - const key = [1, 2, 3]; - const value = 'TestValue'; - - coordinateMap.set(key, value); - coordinateMap.delete(key); - - expect(coordinateMap.has(key)).toBe(false); - }); - - it('should allow changing the joint character', () => { - const coordinateMap = new CoordinateMap(); - const key = [1, 2, 3]; - const value = 'TestValue'; - - coordinateMap.set(key, value); - const newKey = [1, 2, 3]; - const retrievedValue = coordinateMap.get(newKey); - - expect(retrievedValue).toBe(value); - }); -}); - -describe('CoordinateMap', () => { - class MyCoordinateMap extends CoordinateMap { - constructor(joint?: string) { - super(joint); - this._joint = joint += '-'; - } - } - - const cMap = new MyCoordinateMap('*'); - - beforeEach(() => { - cMap.set([0, 0], 0); - cMap.set([0, 1], 1); - cMap.set([1, 1], 11); - }); - it('should joint to be *-', () => { - expect(cMap.joint).toBe('*-'); - }); -}); diff --git a/test/unit/data-structures/hash/coordinate-set.test.ts b/test/unit/data-structures/hash/coordinate-set.test.ts deleted file mode 100644 index bf1d640..0000000 --- a/test/unit/data-structures/hash/coordinate-set.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { CoordinateSet } from '../../../../src'; - -describe('CoordinateSet', () => { - it('should add and check values correctly', () => { - const coordinateSet = new CoordinateSet(); - const value = [1, 2, 3]; - - coordinateSet.add(value); - const hasValue = coordinateSet.has(value); - - expect(hasValue).toBe(true); - }); - - it('should return false when value does not exist', () => { - const coordinateSet = new CoordinateSet(); - const value = [1, 2, 3]; - - expect(coordinateSet.has(value)).toBe(false); - }); - - it('should delete value correctly', () => { - const coordinateSet = new CoordinateSet(); - const value = [1, 2, 3]; - - coordinateSet.add(value); - coordinateSet.delete(value); - - expect(coordinateSet.has(value)).toBe(false); - }); - - it('should allow changing the joint character', () => { - const coordinateSet = new CoordinateSet(); - const value = [1, 2, 3]; - - coordinateSet.add(value); - const newValue = [1, 2, 3]; - const hasValue = coordinateSet.has(newValue); - - expect(hasValue).toBe(true); - }); -}); - -describe('MyCoordinateSet', () => { - class MyCoordinateSet extends CoordinateSet { - constructor(joint?: string) { - super(joint); - this._joint = joint += '-'; - } - } - - const mySet = new MyCoordinateSet('*'); - - beforeEach(() => { - mySet.add([0, 0]); - mySet.add([0, 1]); - mySet.add([1, 1]); - }); - it('should joint to be *-', () => { - expect(mySet.joint).toBe('*-'); - }); - - it('should has, delete', () => { - mySet.delete([0, 1]); - expect(mySet.has([0, 1])).toBe(false); - }); -}); diff --git a/test/unit/data-structures/hash/hash-map.test.ts b/test/unit/data-structures/hash/hash-map.test.ts index 27708e0..2a23c9e 100644 --- a/test/unit/data-structures/hash/hash-map.test.ts +++ b/test/unit/data-structures/hash/hash-map.test.ts @@ -229,3 +229,35 @@ describe('HashMap', () => { expect(hashMap.getAt(1)).toEqual(['key2', 'value2']); }); }); + +describe('HashMap for coordinate object keys', () => { + const hashMap: HashMap<[number, number], number> = new HashMap(); + const codObjs: [number, number][] = []; + + test('set elements in hash map', () => { + for (let i = 0; i < 1000; i++) { + const codObj: [number, number] = [getRandomInt(-10000, 10000), i]; + codObjs.push(codObj); + hashMap.set(codObj, i); + } + }); + + test('get elements in hash map', () => { + for (let i = 0; i < 1000; i++) { + const codObj = codObjs[i]; + if (codObj) { + expect(hashMap.get(codObj)).toBe(i); + } + } + }); + + test('delete elements in hash map', () => { + for (let i = 0; i < 1000; i++) { + if (i === 500) expect(hashMap.size).toBe(500) + const codObj = codObjs[i]; + if (codObj) hashMap.delete(codObj); + } + expect(hashMap.size).toBe(0); + }); + +});