mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
refactor: Eliminate unnecessary data structures. test: Add performance comparison tests with native Map and Set.
This commit is contained in:
parent
b7357def44
commit
1e2013df5e
|
@ -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
|
||||
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
export class CoordinateMap<V> extends Map<any, V> {
|
||||
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));
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
export class CoordinateSet extends Set<any> {
|
||||
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));
|
||||
}
|
||||
}
|
|
@ -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';
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
export class TreeMap {
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
export class TreeSet {
|
||||
}
|
|
@ -23,6 +23,7 @@ if (isCompetitor) {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
suite.add(`${MILLION.toLocaleString()} set & get`, () => {
|
||||
const hm = new HashMap<number, number>();
|
||||
|
||||
|
@ -33,6 +34,41 @@ suite.add(`${MILLION.toLocaleString()} set & get`, () => {
|
|||
hm.get(i);
|
||||
}
|
||||
});
|
||||
|
||||
suite.add(`${MILLION.toLocaleString()} Map set & get`, () => {
|
||||
const hm = new Map<number, number>();
|
||||
|
||||
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<number, number>();
|
||||
|
||||
for (let i = 0; i < MILLION; i++) hm.set(i, i);
|
||||
});
|
||||
|
||||
suite.add(`${MILLION.toLocaleString()} Set add`, () => {
|
||||
const hs = new Set<number>();
|
||||
|
||||
for (let i = 0; i < MILLION; i++) hs.add(i);
|
||||
});
|
||||
|
||||
suite.add(`${MILLION.toLocaleString()} Set add & has`, () => {
|
||||
const hs = new Set<number>();
|
||||
|
||||
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<number, number>();
|
||||
|
@ -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 };
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
import { CoordinateMap } from '../../../../src';
|
||||
|
||||
describe('CoordinateMap', () => {
|
||||
it('should set and get values correctly', () => {
|
||||
const coordinateMap = new CoordinateMap<string>();
|
||||
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<string>();
|
||||
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<string>();
|
||||
const key = [1, 2, 3];
|
||||
|
||||
expect(coordinateMap.has(key)).toBe(false);
|
||||
});
|
||||
|
||||
it('should delete key-value pair correctly', () => {
|
||||
const coordinateMap = new CoordinateMap<string>();
|
||||
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<string>();
|
||||
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<V = any> extends CoordinateMap<V> {
|
||||
constructor(joint?: string) {
|
||||
super(joint);
|
||||
this._joint = joint += '-';
|
||||
}
|
||||
}
|
||||
|
||||
const cMap = new MyCoordinateMap<number>('*');
|
||||
|
||||
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('*-');
|
||||
});
|
||||
});
|
|
@ -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);
|
||||
});
|
||||
});
|
|
@ -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);
|
||||
});
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue