fast-deep-equal vs rfdc vs deep-equal vs is-equal vs equals
Deep Equality Comparison Comparison
1 Year
fast-deep-equalrfdcdeep-equalis-equalequalsSimilar Packages:
What's Deep Equality Comparison?

Deep equality comparison libraries in JavaScript are tools that allow developers to check if two values (which can be primitives, objects, arrays, etc.) are equal in terms of their structure and content, rather than just their reference in memory. This is particularly useful for comparing complex data structures like nested objects and arrays, where a simple equality check (using === or ==) would not suffice. These libraries implement algorithms to traverse the entire structure of the values being compared, ensuring that all properties and elements are checked for equality. This is essential in scenarios like validating form inputs, implementing state management in frameworks, or writing tests where precise comparison of data is required. Each library may have its own approach to handling edge cases, such as circular references, different data types, and performance optimizations, making them suitable for various use cases depending on the requirements of the project.

Package Weekly Downloads Trend
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
fast-deep-equal69,064,5401,997-355 years agoMIT
rfdc26,406,99267827.1 kB19a year agoMIT
deep-equal21,705,83579290.3 kB42 years agoMIT
is-equal118,36860122 kB22 years agoMIT
equals89,83712-39 years agoMIT
Feature Comparison: fast-deep-equal vs rfdc vs deep-equal vs is-equal vs equals

Performance

  • fast-deep-equal:

    fast-deep-equal is one of the fastest libraries for deep equality checks. It is highly optimized for performance, especially when comparing large or deeply nested objects, making it the best choice for performance-critical applications.

  • rfdc:

    rfdc provides fast comparisons, especially for objects with a lot of reference equality. Its unique approach minimizes the time spent on deep comparisons, making it efficient for scenarios where many objects share the same references.

  • deep-equal:

    deep-equal is designed to handle deep comparisons efficiently, but its performance can vary depending on the complexity of the objects being compared. It is not the fastest option for highly nested structures but provides a good balance between accuracy and speed.

  • is-equal:

    is-equal offers good performance with a focus on comprehensive equality checks. It is efficient for most use cases but may not be as fast as fast-deep-equal for large or complex structures.

  • equals:

    equals is lightweight and optimized for performance, making it one of the faster libraries for equality checks. It is particularly effective for comparing simple to moderately complex objects without significant overhead.

Handling Circular References

  • fast-deep-equal:

    fast-deep-equal handles circular references by keeping track of objects that have already been visited during the comparison. This prevents infinite loops and allows for safe comparison of objects with circular structures.

  • rfdc:

    rfdc does not handle circular references in a traditional sense, as it focuses more on reference equality. However, it is designed to be fast and efficient, which helps mitigate issues related to circular structures.

  • deep-equal:

    deep-equal handles circular references gracefully, preventing infinite loops during comparison. It keeps track of visited objects to ensure that circular structures are compared correctly without causing stack overflow errors.

  • is-equal:

    is-equal handles circular references effectively, ensuring that comparisons do not result in infinite loops. It uses a similar approach of tracking visited objects to manage circularity during the comparison process.

  • equals:

    equals does not explicitly handle circular references, which may lead to issues when comparing objects that contain circular structures. It is best used with objects that are known to be acyclic (without circular references).

API Design

  • fast-deep-equal:

    fast-deep-equal provides a simple API focused on performance and accuracy. The library is easy to use, and its documentation highlights its speed advantages, making it appealing for developers who prioritize efficiency.

  • rfdc:

    rfdc has a unique API that focuses on reference equality and fast comparisons. While it may take some time for developers to fully understand its approach, the API is well-documented and encourages efficient usage.

  • deep-equal:

    deep-equal has a simple and intuitive API that makes it easy to use for deep equality checks. The documentation is clear, and the library is straightforward, allowing developers to quickly integrate it into their projects.

  • is-equal:

    is-equal offers a well-designed API that balances simplicity and functionality. It provides clear methods for performing equality checks, and the documentation is thorough, helping developers understand its features quickly.

  • equals:

    equals features a minimalist API that emphasizes simplicity and ease of use. Its design makes it easy to understand and implement, especially for developers who need quick and efficient equality checks without a steep learning curve.

Code Examples

  • fast-deep-equal:

    Fast deep equality with fast-deep-equal

    import isEqual from 'fast-deep-equal';
    
    const a = { name: 'Alice', age: 30, hobbies: ['reading', 'traveling'] };
    const b = { name: 'Alice', age: 30, hobbies: ['reading', 'traveling'] };
    const c = { name: 'Alice', age: 25, hobbies: ['reading', 'traveling'] };
    const d = { name: 'Alice', age: 30, hobbies: ['reading', 'traveling', 'swimming'] };
    const e = a;
    const f = { ...a, hobbies: [...a.hobbies] };
    
    console.log(isEqual(a, b)); // true
    console.log(isEqual(a, c)); // false
    console.log(isEqual(a, d)); // false
    console.log(isEqual(a, e)); // true
    console.log(isEqual(a, f)); // true
    
  • rfdc:

    Reference equality with rfdc

    import rfdc from 'rfdc';
    
    const obj1 = { a: 1, b: { c: 2 } };
    const obj2 = { a: 1, b: { c: 2 } };
    const obj3 = obj1;
    const obj4 = { a: 1, b: { c: 2, d: 3 } };
    const obj5 = { a: 1, b: { c: 2 } };
    const obj6 = { a: 1, b: { c: 2, d: 3 } };
    
    const isEqual = rfdc();
    
    console.log(isEqual(obj1, obj2)); // false (deep comparison)
    console.log(isEqual(obj1, obj3)); // true (reference equality)
    console.log(isEqual(obj1, obj4)); // false (deep comparison)
    console.log(isEqual(obj5, obj6)); // false (deep comparison)
    
  • deep-equal:

    Deep comparison with deep-equal

    import deepEqual from 'deep-equal';
    
    const obj1 = { a: 1, b: { c: 2 } };
    const obj2 = { a: 1, b: { c: 2 } };
    const obj3 = { a: 1, b: { c: 3 } };
    const obj4 = obj1;
    const obj5 = { a: 1, b: { c: 2, d: 4 } };
    
    console.log(deepEqual(obj1, obj2)); // true
    console.log(deepEqual(obj1, obj3)); // false
    console.log(deepEqual(obj1, obj4)); // true
    console.log(deepEqual(obj1, obj5)); // false
    
  • is-equal:

    Comprehensive equality check with is-equal

    import isEqual from 'is-equal';
    
    const obj1 = { a: 1, b: { c: 2 } };
    const obj2 = { a: 1, b: { c: 2 } };
    const obj3 = { a: 1, b: { c: 3 } };
    const obj4 = { a: 1, b: { c: 2, d: 4 } };
    const obj5 = obj1;
    const obj6 = { a: 1, b: { c: 2, d: 4 } };
    
    console.log(isEqual(obj1, obj2)); // true
    console.log(isEqual(obj1, obj3)); // false
    console.log(isEqual(obj1, obj4)); // false
    console.log(isEqual(obj1, obj5)); // true
    console.log(isEqual(obj1, obj6)); // false
    
  • equals:

    Equality check with equals

    import equals from 'equals';
    
    const objA = { x: 10, y: { z: 20 } };
    const objB = { x: 10, y: { z: 20 } };
    const objC = { x: 10, y: { z: 30 } };
    const objD = objA;
    const objE = { x: 10, y: { z: 20, w: 40 } };
    
    console.log(equals(objA, objB)); // true
    console.log(equals(objA, objC)); // false
    console.log(equals(objA, objD)); // true
    console.log(equals(objA, objE)); // false
    
How to Choose: fast-deep-equal vs rfdc vs deep-equal vs is-equal vs equals
  • fast-deep-equal:

    Opt for fast-deep-equal when performance is your top priority. This library is optimized for speed while still providing accurate deep equality checks. It is perfect for applications where comparisons are done frequently and efficiency is essential.

  • rfdc:

    Choose rfdc if you need a unique approach to equality checks that focuses on reference equality and fast comparisons. It is particularly useful for scenarios where you want to minimize the overhead of deep comparisons while still ensuring accuracy.

  • deep-equal:

    Choose deep-equal if you need a reliable and well-tested solution for deep equality checks that handles most edge cases, including circular references. It is suitable for general-purpose use and has a simple API.

  • is-equal:

    Use is-equal if you need a comprehensive solution that provides detailed equality checks with good performance. It is suitable for applications that require a balance between feature richness and efficiency.

  • equals:

    Select equals if you want a lightweight and fast library that focuses on simplicity and performance. It is ideal for projects where size and speed are critical, and you don’t need extensive features.

README for fast-deep-equal

fast-deep-equal

The fastest deep equal with ES6 Map, Set and Typed arrays support.

Build Status npm Coverage Status

Install

npm install fast-deep-equal

Features

  • ES5 compatible
  • works in node.js (8+) and browsers (IE9+)
  • checks equality of Date and RegExp objects by value.

ES6 equal (require('fast-deep-equal/es6')) also supports:

  • Maps
  • Sets
  • Typed arrays

Usage

var equal = require('fast-deep-equal');
console.log(equal({foo: 'bar'}, {foo: 'bar'})); // true

To support ES6 Maps, Sets and Typed arrays equality use:

var equal = require('fast-deep-equal/es6');
console.log(equal(Int16Array([1, 2]), Int16Array([1, 2]))); // true

To use with React (avoiding the traversal of React elements' _owner property that contains circular references and is not needed when comparing the elements - borrowed from react-fast-compare):

var equal = require('fast-deep-equal/react');
var equal = require('fast-deep-equal/es6/react');

Performance benchmark

Node.js v12.6.0:

fast-deep-equal x 261,950 ops/sec ±0.52% (89 runs sampled)
fast-deep-equal/es6 x 212,991 ops/sec ±0.34% (92 runs sampled)
fast-equals x 230,957 ops/sec ±0.83% (85 runs sampled)
nano-equal x 187,995 ops/sec ±0.53% (88 runs sampled)
shallow-equal-fuzzy x 138,302 ops/sec ±0.49% (90 runs sampled)
underscore.isEqual x 74,423 ops/sec ±0.38% (89 runs sampled)
lodash.isEqual x 36,637 ops/sec ±0.72% (90 runs sampled)
deep-equal x 2,310 ops/sec ±0.37% (90 runs sampled)
deep-eql x 35,312 ops/sec ±0.67% (91 runs sampled)
ramda.equals x 12,054 ops/sec ±0.40% (91 runs sampled)
util.isDeepStrictEqual x 46,440 ops/sec ±0.43% (90 runs sampled)
assert.deepStrictEqual x 456 ops/sec ±0.71% (88 runs sampled)

The fastest is fast-deep-equal

To run benchmark (requires node.js 6+):

npm run benchmark

Please note: this benchmark runs against the available test cases. To choose the most performant library for your application, it is recommended to benchmark against your data and to NOT expect this benchmark to reflect the performance difference in your application.

Enterprise support

fast-deep-equal package is a part of Tidelift enterprise subscription - it provides a centralised commercial support to open-source software users, in addition to the support provided by software maintainers.

Security contact

To report a security vulnerability, please use the Tidelift security contact. Tidelift will coordinate the fix and disclosure. Please do NOT report security vulnerability via GitHub issues.

License

MIT