Skip to content

Commit

Permalink
feat!: identity monad
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexXanderGrib committed Jun 25, 2024
1 parent 860b5f4 commit d6a3a41
Show file tree
Hide file tree
Showing 35 changed files with 2,246 additions and 872 deletions.
26 changes: 2 additions & 24 deletions benchmarks/1-object.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,6 @@
import process from "node:process";
import { benchmark } from "./common.js";

const none = { _type: "none" };
const just = (value) => ({ _type: "just", value });

const store = Array(10_000);
const base = process.memoryUsage().heapUsed;
let allocated = 0;

for (let i = 0; i < store.length; i++) {
const random = Math.random();

store[i] = random > 0.5 ? just(random) : none;
allocated += store[i] !== none;
}

const diff = process.memoryUsage().heapUsed - base;
const KB = 1024;

const total = diff;
const perJust = total / allocated;

console.log(
(total / KB).toFixed(2),
"KB -",
Math.ceil(perJust),
"bytes / Just"
);
benchmark({ name: "object", just, none });
26 changes: 2 additions & 24 deletions benchmarks/2-frozen.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,6 @@
import process from "node:process";
import { benchmark } from "./common.js";

const none = Object.freeze({ _type: "none" });
const just = (value) => Object.freeze({ _type: "just", value });

const store = Array(10_000);
const base = process.memoryUsage().heapUsed;

let allocated = 0;

for (let i = 0; i < store.length; i++) {
const random = Math.random();

store[i] = random > 0.5 ? just(random) : none;
allocated += store[i] !== none;
}

const diff = process.memoryUsage().heapUsed - base;
const KB = 1024;
const total = diff;
const perJust = total / allocated;

console.log(
(total / KB).toFixed(2),
"KB -",
Math.ceil(perJust),
"bytes / Just"
);
benchmark({ name: "frozen", just, none });
26 changes: 2 additions & 24 deletions benchmarks/3-class.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import process from "node:process";
import { benchmark } from "./common.js";

class Just {
static create(value) {
Expand All @@ -25,26 +25,4 @@ class None {
}
}

const store = Array(10_000);
const base = process.memoryUsage().heapUsed;

let allocated = 0;

for (let i = 0; i < store.length; i++) {
const random = Math.random();

store[i] = random > 0.5 ? Just.create(random) : None.create();
allocated += store[i] !== None.create();
}

const diff = process.memoryUsage().heapUsed - base;
const KB = 1024;
const total = diff;
const perJust = total / allocated;

console.log(
(total / KB).toFixed(2),
"KB -",
Math.ceil(perJust),
"bytes / Just"
);
benchmark({ name: "class", just: Just.create, none: None.instance });
27 changes: 2 additions & 25 deletions benchmarks/4-enum.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import process from "node:process";
import { benchmark } from "./common.js";

const Type = Object.freeze({
None: 0,
Expand Down Expand Up @@ -30,27 +30,4 @@ class None {
}
}

const store = Array(10_000);
const base = process.memoryUsage().heapUsed;

let allocated = 0;

for (let i = 0; i < store.length; i++) {
const random = Math.random();

store[i] = random > 0.5 ? Just.create(random) : None.create();
allocated += store[i] !== None.create();
}

const diff = process.memoryUsage().heapUsed - base;
const KB = 1024;

const total = diff;
const perJust = total / allocated;

console.log(
(total / KB).toFixed(2),
"KB -",
Math.ceil(perJust),
"bytes / Just"
);
benchmark({ name: "enum", just: Just.create, none: None.instance });
38 changes: 38 additions & 0 deletions benchmarks/5-enum-getter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { benchmark } from "./common.js";

const Type = Object.freeze({
None: 0,
Just: 1
});

class Just {
static create(value) {
return new Just(value);
}

get type() {
return Type.Just;
}

constructor(value) {
this.value = value;
Object.freeze(this);
}
}

class None {
static instance = new None();
static create() {
return None.instance;
}

get type() {
return Type.None;
}

constructor() {
Object.freeze(this);
}
}

benchmark({ name: "enum + getter", just: Just.create, none: None.instance })
61 changes: 0 additions & 61 deletions benchmarks/5-enum-pointer.js

This file was deleted.

42 changes: 42 additions & 0 deletions benchmarks/6-full-name-getter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { benchmark } from "./common.js";

const Type = Object.freeze({
None: "None",
Just: "Just"
});

class Just {
static create(value) {
return new Just(value);
}

get type() {
return Type.Just;
}

constructor(value) {
this.value = value;
Object.freeze(this);
}
}

class None {
static instance = new None();
static create() {
return None.instance;
}

get type() {
return Type.None;
}

constructor() {
Object.freeze(this);
}
}

benchmark({
name: "full type name + getter",
just: Just.create,
none: None.instance
});
43 changes: 43 additions & 0 deletions benchmarks/common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
export function benchmark({
name,
just,
none,
count = 100_000,
iterations = 20
}) {
console.log("Benchmarking implementation:", { name, count, iterations });
const results = [];

for (let i = 0; i < iterations; i++) {
const store = Array(count);
const base = process.memoryUsage().heapUsed;
let allocated = 0;

for (let i = 0; i < store.length; i++) {
const random = Math.random();
const isJust = random > 0.5;

store[i] = random > 0.5 ? just(random) : none;
allocated += isJust;
}

const diff = process.memoryUsage().heapUsed - base;
const KB = 1024;

const total = diff;
const perJust = total / allocated;

results.push(perJust);

console.log(
(total / KB).toFixed(2),
"KB diff -",
Math.ceil(perJust),
"bytes / Just"
);
}

const average = results.reduce((a, b) => a + b, 0) / results.length;

console.log("Benchmark done", { averageBytes: average });
}
Loading

0 comments on commit d6a3a41

Please sign in to comment.