fast-boolean-array 1.2.1 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/index.cjs +89 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +38 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +68 -0
- package/dist/index.js.map +1 -0
- package/package.json +1 -1
- package/src/index.ts +41 -15
- package/test.js +6 -0
- package/bench.js +0 -96
package/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Fast Boolean Array
|
|
2
2
|
|
|
3
|
-
In JavaScript,
|
|
3
|
+
In JavaScript, when working with large arrays of boolean values, a common challenge is efficiently indexing and retrieving these values. Using a regular JavaScript array to store booleans is straightforward, but it is memory-inefficient. While booleans are conceptually 1-bit values, JavaScript engines, like V8 (in Chrome and Node.js), allocate 1 byte (8 bits) per boolean for optimization purposes. This can waste a significant amount of memory when dealing with large arrays.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Fast Boolean Array solves this issue by utilizing bit manipulation to store booleans in a compact format. It uses a Uint8Array and stores each boolean as a single bit within the 8 bits of each byte. This allows you to index and retrieve boolean values by integers (e.g., the 0th boolean, 1st boolean, etc.) while only using a fraction of the memory. Each bit represents a boolean, and you can quickly access or modify a specific boolean using bitwise operations, making it both fast and memory-efficient.
|
|
6
|
+
|
|
7
|
+
For detailed benchmark results, see below.
|
|
6
8
|
|
|
7
9
|
## Features
|
|
8
10
|
|
|
@@ -41,7 +43,6 @@ booleans.set(1, false);
|
|
|
41
43
|
console.log(booleans.get(0)); // Output: true
|
|
42
44
|
console.log(booleans.get(1)); // Output: false
|
|
43
45
|
|
|
44
|
-
|
|
45
46
|
booleans.set(3, false); // will throw as the array is only 3 in size
|
|
46
47
|
console.log(booleans.get(1)); // Output: false
|
|
47
48
|
```
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
default: () => FastBooleanArray
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(src_exports);
|
|
26
|
+
var FastBooleanArray = class {
|
|
27
|
+
size;
|
|
28
|
+
buffer;
|
|
29
|
+
constructor(size) {
|
|
30
|
+
this.size = size;
|
|
31
|
+
this.buffer = new Uint8Array(Math.ceil(size / 8));
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Sets a boolean value at the specified index.
|
|
35
|
+
* @param {number} index - The index to set the boolean value at.
|
|
36
|
+
* @param {number} value - The boolean value to set the `index`.
|
|
37
|
+
* @returns {boolean} The boolean value that was set.
|
|
38
|
+
*/
|
|
39
|
+
set(index, value) {
|
|
40
|
+
if (value) {
|
|
41
|
+
this.buffer[index >> 3] |= 1 << (index & 7);
|
|
42
|
+
return true;
|
|
43
|
+
} else {
|
|
44
|
+
this.buffer[index >> 3] &= ~(1 << (index & 7));
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* like `set` but throws if the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
50
|
+
* @param {number} index - The index to set the boolean value at.
|
|
51
|
+
* @param {number} value - The boolean value to set the `index`.
|
|
52
|
+
* @returns {boolean} The boolean value that was set.
|
|
53
|
+
* @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
54
|
+
*/
|
|
55
|
+
setSafe(index, value) {
|
|
56
|
+
if (index < 0 || index >= this.size) {
|
|
57
|
+
throw new RangeError("Index out of bounds");
|
|
58
|
+
}
|
|
59
|
+
return this.set(index, value);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Gets a boolean value at the specified index.
|
|
63
|
+
* @param {number} index - The index to get the boolean value of.
|
|
64
|
+
* @returns {boolean} The boolean value that was set.
|
|
65
|
+
* @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
66
|
+
*/
|
|
67
|
+
get(index) {
|
|
68
|
+
return (this.buffer[index >> 3] & 1 << index % 8) !== 0;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* like `get` but throws if the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
72
|
+
* @param {number} index - The index to get the boolean value of.
|
|
73
|
+
* @returns {boolean} The boolean value that was set.
|
|
74
|
+
* @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
75
|
+
*/
|
|
76
|
+
getSafe(index) {
|
|
77
|
+
if (index < 0 || index >= this.size) {
|
|
78
|
+
throw new RangeError("Index out of bounds");
|
|
79
|
+
}
|
|
80
|
+
return this.get(index);
|
|
81
|
+
}
|
|
82
|
+
get length() {
|
|
83
|
+
return this.size;
|
|
84
|
+
}
|
|
85
|
+
set length(_value) {
|
|
86
|
+
throw new Error("Setting the length on BooleanArray's is not supported");
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export default class FastBooleanArray {\r\n\tpublic size: number;\r\n\tprivate buffer: Uint8Array;\r\n\r\n\tconstructor(size: number) {\r\n\t\tthis.size = size;\r\n\t\tthis.buffer = new Uint8Array(Math.ceil(size / 8)); // Allocate memory\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a boolean value at the specified index.\r\n\t * @param {number} index - The index to set the boolean value at.\r\n\t * @param {number} value - The boolean value to set the `index`.\r\n\t * @returns {boolean} The boolean value that was set.\r\n\t */\r\n\tset(index: number, value: any) {\r\n\t\tif (value) {\r\n\t\t\tthis.buffer[index >> 3] |= 1 << (index & 7); // Set bit\r\n\t\t\treturn true;\r\n\t\t} else {\r\n\t\t\tthis.buffer[index >> 3] &= ~(1 << (index & 7)); // Clear bit\r\n\t\t\treturn false;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * like `set` but throws if the index is out of bounds (less than 0 or greater than or equal to the array size).\r\n\t * @param {number} index - The index to set the boolean value at.\r\n\t * @param {number} value - The boolean value to set the `index`.\r\n\t * @returns {boolean} The boolean value that was set.\r\n\t * @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).\r\n\t */\r\n\tsetSafe(index: number, value: any) {\r\n\t\tif (index < 0 || index >= this.size) {\r\n\t\t\tthrow new RangeError('Index out of bounds');\r\n\t\t}\r\n\t\treturn this.set(index, value);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets a boolean value at the specified index.\r\n\t * @param {number} index - The index to get the boolean value of.\r\n\t * @returns {boolean} The boolean value that was set.\r\n\t * @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).\r\n\t */\r\n\tget(index: number) {\r\n\t\treturn (this.buffer[index >> 3] & (1 << index % 8)) !== 0; // Check bit\r\n\t}\r\n\r\n\t/**\r\n\t * like `get` but throws if the index is out of bounds (less than 0 or greater than or equal to the array size).\r\n\t * @param {number} index - The index to get the boolean value of.\r\n\t * @returns {boolean} The boolean value that was set.\r\n\t * @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).\r\n\t */\r\n\tgetSafe(index: number) {\r\n\t\tif (index < 0 || index >= this.size) {\r\n\t\t\tthrow new RangeError('Index out of bounds');\r\n\t\t}\r\n\t\treturn this.get(index);\r\n\t}\r\n\r\n\tget length() {\r\n\t\treturn this.size;\r\n\t}\r\n\r\n\tset length(_value: number) {\r\n\t\tthrow new Error(\"Setting the length on BooleanArray's is not supported\");\r\n\t}\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAqB,mBAArB,MAAsC;AAAA,EAC9B;AAAA,EACC;AAAA,EAER,YAAY,MAAc;AACzB,SAAK,OAAO;AACZ,SAAK,SAAS,IAAI,WAAW,KAAK,KAAK,OAAO,CAAC,CAAC;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,OAAe,OAAY;AAC9B,QAAI,OAAO;AACV,WAAK,OAAO,SAAS,CAAC,KAAK,MAAM,QAAQ;AACzC,aAAO;AAAA,IACR,OAAO;AACN,WAAK,OAAO,SAAS,CAAC,KAAK,EAAE,MAAM,QAAQ;AAC3C,aAAO;AAAA,IACR;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,QAAQ,OAAe,OAAY;AAClC,QAAI,QAAQ,KAAK,SAAS,KAAK,MAAM;AACpC,YAAM,IAAI,WAAW,qBAAqB;AAAA,IAC3C;AACA,WAAO,KAAK,IAAI,OAAO,KAAK;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,OAAe;AAClB,YAAQ,KAAK,OAAO,SAAS,CAAC,IAAK,KAAK,QAAQ,OAAQ;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAQ,OAAe;AACtB,QAAI,QAAQ,KAAK,SAAS,KAAK,MAAM;AACpC,YAAM,IAAI,WAAW,qBAAqB;AAAA,IAC3C;AACA,WAAO,KAAK,IAAI,KAAK;AAAA,EACtB;AAAA,EAEA,IAAI,SAAS;AACZ,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,IAAI,OAAO,QAAgB;AAC1B,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACxE;AACD;","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
declare class FastBooleanArray {
|
|
2
|
+
size: number;
|
|
3
|
+
private buffer;
|
|
4
|
+
constructor(size: number);
|
|
5
|
+
/**
|
|
6
|
+
* Sets a boolean value at the specified index.
|
|
7
|
+
* @param {number} index - The index to set the boolean value at.
|
|
8
|
+
* @param {number} value - The boolean value to set the `index`.
|
|
9
|
+
* @returns {boolean} The boolean value that was set.
|
|
10
|
+
*/
|
|
11
|
+
set(index: number, value: any): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* like `set` but throws if the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
14
|
+
* @param {number} index - The index to set the boolean value at.
|
|
15
|
+
* @param {number} value - The boolean value to set the `index`.
|
|
16
|
+
* @returns {boolean} The boolean value that was set.
|
|
17
|
+
* @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
18
|
+
*/
|
|
19
|
+
setSafe(index: number, value: any): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Gets a boolean value at the specified index.
|
|
22
|
+
* @param {number} index - The index to get the boolean value of.
|
|
23
|
+
* @returns {boolean} The boolean value that was set.
|
|
24
|
+
* @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
25
|
+
*/
|
|
26
|
+
get(index: number): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* like `get` but throws if the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
29
|
+
* @param {number} index - The index to get the boolean value of.
|
|
30
|
+
* @returns {boolean} The boolean value that was set.
|
|
31
|
+
* @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
32
|
+
*/
|
|
33
|
+
getSafe(index: number): boolean;
|
|
34
|
+
get length(): number;
|
|
35
|
+
set length(_value: number);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { FastBooleanArray as default };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
declare class FastBooleanArray {
|
|
2
|
+
size: number;
|
|
3
|
+
private buffer;
|
|
4
|
+
constructor(size: number);
|
|
5
|
+
/**
|
|
6
|
+
* Sets a boolean value at the specified index.
|
|
7
|
+
* @param {number} index - The index to set the boolean value at.
|
|
8
|
+
* @param {number} value - The boolean value to set the `index`.
|
|
9
|
+
* @returns {boolean} The boolean value that was set.
|
|
10
|
+
*/
|
|
11
|
+
set(index: number, value: any): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* like `set` but throws if the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
14
|
+
* @param {number} index - The index to set the boolean value at.
|
|
15
|
+
* @param {number} value - The boolean value to set the `index`.
|
|
16
|
+
* @returns {boolean} The boolean value that was set.
|
|
17
|
+
* @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
18
|
+
*/
|
|
19
|
+
setSafe(index: number, value: any): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Gets a boolean value at the specified index.
|
|
22
|
+
* @param {number} index - The index to get the boolean value of.
|
|
23
|
+
* @returns {boolean} The boolean value that was set.
|
|
24
|
+
* @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
25
|
+
*/
|
|
26
|
+
get(index: number): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* like `get` but throws if the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
29
|
+
* @param {number} index - The index to get the boolean value of.
|
|
30
|
+
* @returns {boolean} The boolean value that was set.
|
|
31
|
+
* @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
32
|
+
*/
|
|
33
|
+
getSafe(index: number): boolean;
|
|
34
|
+
get length(): number;
|
|
35
|
+
set length(_value: number);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { FastBooleanArray as default };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var FastBooleanArray = class {
|
|
3
|
+
size;
|
|
4
|
+
buffer;
|
|
5
|
+
constructor(size) {
|
|
6
|
+
this.size = size;
|
|
7
|
+
this.buffer = new Uint8Array(Math.ceil(size / 8));
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Sets a boolean value at the specified index.
|
|
11
|
+
* @param {number} index - The index to set the boolean value at.
|
|
12
|
+
* @param {number} value - The boolean value to set the `index`.
|
|
13
|
+
* @returns {boolean} The boolean value that was set.
|
|
14
|
+
*/
|
|
15
|
+
set(index, value) {
|
|
16
|
+
if (value) {
|
|
17
|
+
this.buffer[index >> 3] |= 1 << (index & 7);
|
|
18
|
+
return true;
|
|
19
|
+
} else {
|
|
20
|
+
this.buffer[index >> 3] &= ~(1 << (index & 7));
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* like `set` but throws if the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
26
|
+
* @param {number} index - The index to set the boolean value at.
|
|
27
|
+
* @param {number} value - The boolean value to set the `index`.
|
|
28
|
+
* @returns {boolean} The boolean value that was set.
|
|
29
|
+
* @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
30
|
+
*/
|
|
31
|
+
setSafe(index, value) {
|
|
32
|
+
if (index < 0 || index >= this.size) {
|
|
33
|
+
throw new RangeError("Index out of bounds");
|
|
34
|
+
}
|
|
35
|
+
return this.set(index, value);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Gets a boolean value at the specified index.
|
|
39
|
+
* @param {number} index - The index to get the boolean value of.
|
|
40
|
+
* @returns {boolean} The boolean value that was set.
|
|
41
|
+
* @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
42
|
+
*/
|
|
43
|
+
get(index) {
|
|
44
|
+
return (this.buffer[index >> 3] & 1 << index % 8) !== 0;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* like `get` but throws if the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
48
|
+
* @param {number} index - The index to get the boolean value of.
|
|
49
|
+
* @returns {boolean} The boolean value that was set.
|
|
50
|
+
* @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
51
|
+
*/
|
|
52
|
+
getSafe(index) {
|
|
53
|
+
if (index < 0 || index >= this.size) {
|
|
54
|
+
throw new RangeError("Index out of bounds");
|
|
55
|
+
}
|
|
56
|
+
return this.get(index);
|
|
57
|
+
}
|
|
58
|
+
get length() {
|
|
59
|
+
return this.size;
|
|
60
|
+
}
|
|
61
|
+
set length(_value) {
|
|
62
|
+
throw new Error("Setting the length on BooleanArray's is not supported");
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
export {
|
|
66
|
+
FastBooleanArray as default
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export default class FastBooleanArray {\r\n\tpublic size: number;\r\n\tprivate buffer: Uint8Array;\r\n\r\n\tconstructor(size: number) {\r\n\t\tthis.size = size;\r\n\t\tthis.buffer = new Uint8Array(Math.ceil(size / 8)); // Allocate memory\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a boolean value at the specified index.\r\n\t * @param {number} index - The index to set the boolean value at.\r\n\t * @param {number} value - The boolean value to set the `index`.\r\n\t * @returns {boolean} The boolean value that was set.\r\n\t */\r\n\tset(index: number, value: any) {\r\n\t\tif (value) {\r\n\t\t\tthis.buffer[index >> 3] |= 1 << (index & 7); // Set bit\r\n\t\t\treturn true;\r\n\t\t} else {\r\n\t\t\tthis.buffer[index >> 3] &= ~(1 << (index & 7)); // Clear bit\r\n\t\t\treturn false;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * like `set` but throws if the index is out of bounds (less than 0 or greater than or equal to the array size).\r\n\t * @param {number} index - The index to set the boolean value at.\r\n\t * @param {number} value - The boolean value to set the `index`.\r\n\t * @returns {boolean} The boolean value that was set.\r\n\t * @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).\r\n\t */\r\n\tsetSafe(index: number, value: any) {\r\n\t\tif (index < 0 || index >= this.size) {\r\n\t\t\tthrow new RangeError('Index out of bounds');\r\n\t\t}\r\n\t\treturn this.set(index, value);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets a boolean value at the specified index.\r\n\t * @param {number} index - The index to get the boolean value of.\r\n\t * @returns {boolean} The boolean value that was set.\r\n\t * @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).\r\n\t */\r\n\tget(index: number) {\r\n\t\treturn (this.buffer[index >> 3] & (1 << index % 8)) !== 0; // Check bit\r\n\t}\r\n\r\n\t/**\r\n\t * like `get` but throws if the index is out of bounds (less than 0 or greater than or equal to the array size).\r\n\t * @param {number} index - The index to get the boolean value of.\r\n\t * @returns {boolean} The boolean value that was set.\r\n\t * @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).\r\n\t */\r\n\tgetSafe(index: number) {\r\n\t\tif (index < 0 || index >= this.size) {\r\n\t\t\tthrow new RangeError('Index out of bounds');\r\n\t\t}\r\n\t\treturn this.get(index);\r\n\t}\r\n\r\n\tget length() {\r\n\t\treturn this.size;\r\n\t}\r\n\r\n\tset length(_value: number) {\r\n\t\tthrow new Error(\"Setting the length on BooleanArray's is not supported\");\r\n\t}\r\n}\r\n"],"mappings":";AAAA,IAAqB,mBAArB,MAAsC;AAAA,EAC9B;AAAA,EACC;AAAA,EAER,YAAY,MAAc;AACzB,SAAK,OAAO;AACZ,SAAK,SAAS,IAAI,WAAW,KAAK,KAAK,OAAO,CAAC,CAAC;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,OAAe,OAAY;AAC9B,QAAI,OAAO;AACV,WAAK,OAAO,SAAS,CAAC,KAAK,MAAM,QAAQ;AACzC,aAAO;AAAA,IACR,OAAO;AACN,WAAK,OAAO,SAAS,CAAC,KAAK,EAAE,MAAM,QAAQ;AAC3C,aAAO;AAAA,IACR;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,QAAQ,OAAe,OAAY;AAClC,QAAI,QAAQ,KAAK,SAAS,KAAK,MAAM;AACpC,YAAM,IAAI,WAAW,qBAAqB;AAAA,IAC3C;AACA,WAAO,KAAK,IAAI,OAAO,KAAK;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,OAAe;AAClB,YAAQ,KAAK,OAAO,SAAS,CAAC,IAAK,KAAK,QAAQ,OAAQ;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAQ,OAAe;AACtB,QAAI,QAAQ,KAAK,SAAS,KAAK,MAAM;AACpC,YAAM,IAAI,WAAW,qBAAqB;AAAA,IAC3C;AACA,WAAO,KAAK,IAAI,KAAK;AAAA,EACtB;AAAA,EAEA,IAAI,SAAS;AACZ,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,IAAI,OAAO,QAAgB;AAC1B,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACxE;AACD;","names":[]}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -8,37 +8,63 @@ export default class FastBooleanArray {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
* @
|
|
11
|
+
* Sets a boolean value at the specified index.
|
|
12
|
+
* @param {number} index - The index to set the boolean value at.
|
|
13
|
+
* @param {number} value - The boolean value to set the `index`.
|
|
14
|
+
* @returns {boolean} The boolean value that was set.
|
|
13
15
|
*/
|
|
14
|
-
set(
|
|
15
|
-
if (input < 0 || input >= this.size) {
|
|
16
|
-
throw new RangeError('Index out of bounds');
|
|
17
|
-
}
|
|
16
|
+
set(index: number, value: any) {
|
|
18
17
|
if (value) {
|
|
19
|
-
this.buffer[
|
|
18
|
+
this.buffer[index >> 3] |= 1 << (index & 7); // Set bit
|
|
19
|
+
return true;
|
|
20
20
|
} else {
|
|
21
|
-
this.buffer[
|
|
21
|
+
this.buffer[index >> 3] &= ~(1 << (index & 7)); // Clear bit
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* like `set` but throws if the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
28
|
+
* @param {number} index - The index to set the boolean value at.
|
|
29
|
+
* @param {number} value - The boolean value to set the `index`.
|
|
30
|
+
* @returns {boolean} The boolean value that was set.
|
|
31
|
+
* @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
32
|
+
*/
|
|
33
|
+
setSafe(index: number, value: any) {
|
|
34
|
+
if (index < 0 || index >= this.size) {
|
|
35
|
+
throw new RangeError('Index out of bounds');
|
|
22
36
|
}
|
|
23
|
-
return value;
|
|
37
|
+
return this.set(index, value);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Gets a boolean value at the specified index.
|
|
42
|
+
* @param {number} index - The index to get the boolean value of.
|
|
43
|
+
* @returns {boolean} The boolean value that was set.
|
|
44
|
+
* @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
45
|
+
*/
|
|
46
|
+
get(index: number) {
|
|
47
|
+
return (this.buffer[index >> 3] & (1 << index % 8)) !== 0; // Check bit
|
|
24
48
|
}
|
|
25
49
|
|
|
26
50
|
/**
|
|
27
|
-
*
|
|
28
|
-
* @
|
|
51
|
+
* like `get` but throws if the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
52
|
+
* @param {number} index - The index to get the boolean value of.
|
|
53
|
+
* @returns {boolean} The boolean value that was set.
|
|
54
|
+
* @throws {RangeError} If the index is out of bounds (less than 0 or greater than or equal to the array size).
|
|
29
55
|
*/
|
|
30
|
-
|
|
31
|
-
if (
|
|
56
|
+
getSafe(index: number) {
|
|
57
|
+
if (index < 0 || index >= this.size) {
|
|
32
58
|
throw new RangeError('Index out of bounds');
|
|
33
59
|
}
|
|
34
|
-
return
|
|
60
|
+
return this.get(index);
|
|
35
61
|
}
|
|
36
62
|
|
|
37
63
|
get length() {
|
|
38
64
|
return this.size;
|
|
39
65
|
}
|
|
40
66
|
|
|
41
|
-
set length(
|
|
67
|
+
set length(_value: number) {
|
|
42
68
|
throw new Error("Setting the length on BooleanArray's is not supported");
|
|
43
69
|
}
|
|
44
70
|
}
|
package/test.js
ADDED
package/bench.js
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import BooleanArray from './dist/index.js';
|
|
2
|
-
import { performance } from 'node:perf_hooks';
|
|
3
|
-
import { serialize } from 'v8';
|
|
4
|
-
|
|
5
|
-
function getMemoryUsageOfReference(ref) {
|
|
6
|
-
const serialized = serialize(ref); // Convert the reference to a Buffer
|
|
7
|
-
return serialized.length; // The size of the serialized Buffer in bytes
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function testVanillaArraySet(amount, analyzeMemory = true) {
|
|
11
|
-
const vanillaArray = [];
|
|
12
|
-
const startTime = performance.now();
|
|
13
|
-
for (let i = 0; i < amount; i++) {
|
|
14
|
-
vanillaArray[i] = true;
|
|
15
|
-
}
|
|
16
|
-
const endTime = performance.now();
|
|
17
|
-
const usedMemory = analyzeMemory ? getMemoryUsageOfReference(vanillaArray) : 0;
|
|
18
|
-
return { vanillaArray, usedMemory, startTime, endTime };
|
|
19
|
-
}
|
|
20
|
-
testVanillaArraySet._name = 'Set Vanilla array ';
|
|
21
|
-
|
|
22
|
-
function testBooleanArraySet(amount, analyzeMemory = true) {
|
|
23
|
-
const theBooleanArray = new BooleanArray(amount);
|
|
24
|
-
const startTime = performance.now();
|
|
25
|
-
for (let i = 0; i < amount; i++) {
|
|
26
|
-
theBooleanArray.set(i, true);
|
|
27
|
-
}
|
|
28
|
-
const endTime = performance.now();
|
|
29
|
-
const usedMemory = analyzeMemory ? getMemoryUsageOfReference(theBooleanArray) : 0;
|
|
30
|
-
return { theBooleanArray, usedMemory, startTime, endTime };
|
|
31
|
-
}
|
|
32
|
-
testBooleanArraySet._name = 'Set Fast Boolean Array';
|
|
33
|
-
|
|
34
|
-
function testVanillaArrayGet(amount) {
|
|
35
|
-
const { vanillaArray } = testVanillaArraySet(amount, false);
|
|
36
|
-
const startTime = performance.now();
|
|
37
|
-
for (let i = 0; i < amount; i++) {
|
|
38
|
-
vanillaArray[i];
|
|
39
|
-
}
|
|
40
|
-
const endTime = performance.now();
|
|
41
|
-
return {
|
|
42
|
-
usedMemory: 0,
|
|
43
|
-
startTime,
|
|
44
|
-
endTime
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
testVanillaArrayGet._name = 'Get Vanilla array ';
|
|
48
|
-
|
|
49
|
-
function testBooleanArrayGet(amount) {
|
|
50
|
-
const { theBooleanArray } = testBooleanArraySet(amount, false);
|
|
51
|
-
const startTime = performance.now();
|
|
52
|
-
for (let i = 0; i < amount; i++) {
|
|
53
|
-
theBooleanArray.get(i, true);
|
|
54
|
-
}
|
|
55
|
-
const endTime = performance.now();
|
|
56
|
-
return {
|
|
57
|
-
usedMemory: 0,
|
|
58
|
-
startTime,
|
|
59
|
-
endTime
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
testBooleanArrayGet._name = 'Get Fast Boolean Array';
|
|
63
|
-
|
|
64
|
-
function performanceTest(test, amount) {
|
|
65
|
-
const runs = 1000; // Number of times to run the test
|
|
66
|
-
let totalTime = 0;
|
|
67
|
-
let totalMemory = 0;
|
|
68
|
-
|
|
69
|
-
for (let i = 0; i < runs; i++) {
|
|
70
|
-
const { startTime, endTime, usedMemory } = test(amount);
|
|
71
|
-
|
|
72
|
-
totalTime += endTime - startTime;
|
|
73
|
-
totalMemory += usedMemory;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const averageTime = (totalTime / runs).toFixed(8);
|
|
77
|
-
const averageMemory = totalMemory / runs;
|
|
78
|
-
|
|
79
|
-
console.log(
|
|
80
|
-
`${test._name}: ${averageTime} ms | ${test.name.includes('Set') ? averageMemory + ' Bytes' : 'N/A'} | ${amount} indexes`
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Run tests
|
|
85
|
-
console.clear();
|
|
86
|
-
[1, 100, 1_000, 10_000, 100_000, 1_000_000, 10_000_000].forEach(async (amount) => {
|
|
87
|
-
console.log('');
|
|
88
|
-
[testVanillaArraySet, testBooleanArraySet, testVanillaArrayGet, testBooleanArrayGet].forEach(
|
|
89
|
-
(test) => {
|
|
90
|
-
performanceTest(test, amount);
|
|
91
|
-
}
|
|
92
|
-
);
|
|
93
|
-
await new Promise((resolve) => {
|
|
94
|
-
setTimeout(resolve, 5_000); // Let garbadge collection do its thing for more accurate memory logging
|
|
95
|
-
});
|
|
96
|
-
});
|