Skip to content

Commit

Permalink
unary functions
Browse files Browse the repository at this point in the history
  • Loading branch information
kubikowski committed Jun 9, 2024
1 parent 4678a37 commit 24f1060
Show file tree
Hide file tree
Showing 13 changed files with 118 additions and 8 deletions.
1 change: 1 addition & 0 deletions .run/test_scale.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<script value="test:scale" />
</scripts>
<node-interpreter value="project" />
<node-options value="--max-old-space-size=8192" />
<envs />
<method v="2" />
</configuration>
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"pretest:coverage": "rimraf coverage",
"test": "jest --testPathIgnorePatterns=scale",
"test:coverage": "jest --collect-coverage --testPathIgnorePatterns=scale",
"test:metrics": "jest test/scale/performance-metrics.scale.test.ts",
"test:scale": "jest test/scale/scale.test.ts"
},
"dependencies": {},
Expand Down
12 changes: 9 additions & 3 deletions src/comparisons/pairwise-disjoint.function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,19 @@ export function pairwiseDisjoint<T>(...sets: ReadonlySet<T>[]): boolean {
return true;
}

const allElements = new Set<T>([ ...primarySet, ...secondarySet ]);
const disjointUnion = new Set<T>();
for (const set of [ primarySet, secondarySet ]) {
for (const element of set) {
disjointUnion.add(element);
}
}

for (const set of sets) {
for (const element of set) {
if (allElements.has(element)) {
if (disjointUnion.has(element)) {
return false;
} else {
allElements.add(element);
disjointUnion.add(element);
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@ export { intersection } from './operations/intersection.function.js';
export { union } from './operations/union.function.js';
export { xor } from './operations/xor.function.js';

export { sort } from './ordering/sort.function.js';
export { copy } from './unary/copy.function.js';
export { map } from './unary/map.function.js';
export { filter } from './unary/filter.function.js';
export { sort } from './unary/sort.function.js';
4 changes: 3 additions & 1 deletion src/operations/difference.function.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { copy } from '../unary/copy.function';

export function difference<T>(...sets: Set<T>[]): Set<T>;
export function difference<T>(...sets: ReadonlySet<T>[]): ReadonlySet<T>;

Expand All @@ -12,7 +14,7 @@ export function difference<T>(...sets: ReadonlySet<T>[]): ReadonlySet<T>;
*/
export function difference<T>(...sets: ReadonlySet<T>[]): ReadonlySet<T> {
if (sets.length < 2) {
return new Set<T>(sets.shift());
return copy(sets.shift() ?? new Set<T>());
}

const resultSet = new Set<T>();
Expand Down
4 changes: 3 additions & 1 deletion src/operations/intersection.function.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { copy } from '../unary/copy.function';

export function intersection<T>(...sets: Set<T>[]): Set<T>;
export function intersection<T>(...sets: ReadonlySet<T>[]): ReadonlySet<T>;

Expand All @@ -11,7 +13,7 @@ export function intersection<T>(...sets: ReadonlySet<T>[]): ReadonlySet<T>;
*/
export function intersection<T>(...sets: ReadonlySet<T>[]): ReadonlySet<T> {
if (sets.length < 2) {
return new Set<T>(sets.shift());
return copy(sets.shift() ?? new Set<T>());
}

const resultSet = new Set<T>();
Expand Down
2 changes: 1 addition & 1 deletion src/operations/union.function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function union<T>(...sets: ReadonlySet<T>[]): ReadonlySet<T>;
* @description A ∪ B ≔ { x : (x ∈ A) ∨ (x ∈ B) }
*/
export function union<T>(...sets: ReadonlySet<T>[]): ReadonlySet<T> {
const resultSet = new Set<T>(sets.shift());
const resultSet = new Set<T>();

for (const set of sets) {
for (const element of set) {
Expand Down
4 changes: 3 additions & 1 deletion src/operations/xor.function.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { copy } from '../unary/copy.function';

export function xor<T>(...sets: Set<T>[]): Set<T>;
export function xor<T>(...sets: ReadonlySet<T>[]): ReadonlySet<T>;

Expand All @@ -14,7 +16,7 @@ export function xor<T>(...sets: ReadonlySet<T>[]): ReadonlySet<T>;
*/
export function xor<T>(...sets: ReadonlySet<T>[]): ReadonlySet<T> {
if (sets.length < 2) {
return new Set<T>(sets.shift());
return copy(sets.shift() ?? new Set<T>());
}

const resultSet = new Set<T>();
Expand Down
12 changes: 12 additions & 0 deletions src/unary/copy.function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export function copy<T>(set: Set<T>): Set<T>;
export function copy<T>(set: ReadonlySet<T>): ReadonlySet<T>;

export function copy<T>(set: ReadonlySet<T>): ReadonlySet<T> {
const resultSet = new Set<T>();

for (const element of set) {
resultSet.add(element);
}

return resultSet;
}
14 changes: 14 additions & 0 deletions src/unary/filter.function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export function filter<T>(set: Set<T>, filterFunction: (element: T) => boolean): Set<T>;
export function filter<T>(set: ReadonlySet<T>, filterFunction: (element: T) => boolean): ReadonlySet<T>;

export function filter<T>(set: ReadonlySet<T>, filterFunction: (element: T) => boolean): ReadonlySet<T> {
const resultSet = new Set<T>();

for (const element of set) {
if (filterFunction(element)) {
resultSet.add(element);
}
}

return resultSet;
}
12 changes: 12 additions & 0 deletions src/unary/map.function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export function map<T, R>(set: Set<T>, mappingFunction: (element: T) => R): Set<R>;
export function map<T, R>(set: ReadonlySet<T>, mappingFunction: (element: T) => R): ReadonlySet<R>;

export function map<T, R>(set: ReadonlySet<T>, mappingFunction: (element: T) => R): ReadonlySet<R> {
const resultSet = new Set<R>();

for (const element of set) {
resultSet.add(mappingFunction(element));
}

return resultSet;
}
File renamed without changes.
55 changes: 55 additions & 0 deletions test/scale/performance-metrics.scale.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { describe, expect, it } from '@jest/globals';
import { ScaleTestSets } from '../util/scale/scale-test-sets.model';
import { Timer } from '../util/scale/timer.model';

describe('performance metrics', () => {

describe('copying one set', () => {
const { multiplesOf1 } = ScaleTestSets;

time('one set ⋅ direct copy', () => new Set(multiplesOf1));
time('one set ⋅ array copy', () => new Set([ ...multiplesOf1 ]));
time('one set ⋅ adding elements', () => {
const set = new Set<number>();
for (const element of multiplesOf1) set.add(element);
return set;
});
});

describe('copying two sets', () => {
const { multiplesOf2, multiplesOf2B } = ScaleTestSets;

time('two sets ⋅ array copy', () => new Set([ ...multiplesOf2, ...multiplesOf2B ]));
time('two sets ⋅ adding elements', () => {
const set = new Set<number>();
for (const element of multiplesOf2) set.add(element);
for (const element of multiplesOf2B) set.add(element);
return set;
});
});

describe('copying three sets', () => {
const { multiplesOf3, multiplesOf3B, multiplesOf3C } = ScaleTestSets;

time('three sets ⋅ array copy', () => new Set([ ...multiplesOf3, ...multiplesOf3B, ...multiplesOf3C ]));
time('three sets ⋅ adding elements', () => {
const set = new Set<number>();
for (const element of multiplesOf3) set.add(element);
for (const element of multiplesOf3B) set.add(element);
for (const element of multiplesOf3C) set.add(element);
return set;
});
});
});

function time(methodName: string, method: () => Set<number>): void {
it(methodName, () => {
for (let index = 0; index < 50; index++) {
if (index > 0 && index % 10 === 0) Timer.nextLine(methodName);
const result = Timer.time(methodName, method);
expect(result.size).toBe(15_000_000);
}

Timer.log(methodName);
});
}

0 comments on commit 24f1060

Please sign in to comment.