var object = {
items: Array.from({
length: 100
}, (_, i) => ({
id: i,
name: `Item-${i}`,
}))
};
// Randomly select ~75% of items
var selectedItems = object.items
.filter(() => Math.random() > 0.25)
.map(item => item.id);
return object.items.every(({ id }) => selectedItems.includes(id));
return ((selected) => object.items.every(({ id }) => selected.has(id)))(
new Set(selectedItems)
);
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
Array.every => Array.includes | |
Array.every => Set.has with new Set() creation |
Test name | Executions per second |
---|---|
Array.every => Array.includes | 44636192.0 Ops/sec |
Array.every => Set.has with new Set() creation | 840470.5 Ops/sec |
The benchmark compares two different approaches to check if every item in an array is included in a set of selected IDs. The first approach utilizes the Array.every
method combined with Array.includes
, while the second approach employs Array.every
along with Set.has
for a set created from selectedItems
. This comparison highlights the efficiency differences between these two techniques in checking for the presence of elements.
Test Case 1: Array.every => Array.includes
return object.items.every(({ id }) => selectedItems.includes(id));
object.items
array and checks if its id
is included in the selectedItems
array using Array.includes
.Array.includes
performs a linear search, which results in O(n*m) complexity, where n is the size of object.items
and m is the size of selectedItems
. This can lead to performance bottlenecks if both arrays are large.Test Case 2: Array.every => Set.has with new Set() creation
return ((selected) => object.items.every(({ id }) => selected.has(id)))(new Set(selectedItems));
Set
is created from the selectedItems
array. The Array.every
method is used again, but this time it checks if the Set
contains each id
via Set.has
.Set.has
provides average constant time complexity O(1) for lookup, leading to an overall time complexity of O(n) for this test case. This is significantly better than the previous approach, especially as the sizes of the arrays grow.Set
is optimized for such operations.Set
from selectedItems
.Set
, but this is generally offset by the faster lookups.From the benchmark results, we see the following performance metrics:
Array.every => Array.includes
: Executes approximately 44,636,192 times per second.Array.every => Set.has with new Set() creation
: Executes approximately 840,470 times per second.The results clearly indicate that the Set.has
approach is significantly faster than using Array.includes
, highlighting the benefits of using data structures optimized for performance in specific use cases.
Other Alternatives:
Array.includes
or Set.has
to avoid the overhead of creating a new Array
or Set
iteratively. filter
+ length
: This could be another way to check for inclusion, but it would also face the same performance limitations as the Array.includes
method._.intersection
to find common elements, which may provide better performance in certain scenarios. However, the benefits would heavily depend on how these are implemented under-the-hood.Overall, understanding the distinctions between these approaches allows software engineers to choose the most efficient method based on the size of the data set and the specific requirements of their application.