Js-sdsl

Javascript 标准数据结构库
授权协议 MIT
开发语言 TypeScript
所属分类 Web应用开发、 常用JavaScript包
软件类型 开源软件
地区 国产
投 递 者 拓拔意
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

众所周知,Javascript 并不像 C++ 或者 Java 这些语言一样拥有较为完善的数据结构库,Js 的相关体系十分匮乏,甚至不提供这样的常见对象。

好消息是,Js 在 es6 中提供了 Set(WeakSet) 和 Map(WeakMap),这是一种哈希表结构,为其匮乏的数据结构体系增添了一丝色彩,但不幸的是,在许多老版本的浏览器中,SetMap 不被支持,并且相关的 polifill 相较于原生实现十分低效

为了解决这种局面,我们以 C++ STL 为参考开发了 Js-sdsl 这一数据结构库,目前包含堆、红黑树、哈希表等多种数据结构,在未来,我们会开发更多的通用数据结构来增加其丰富性

在浏览器兼容上,其采用 ES5 语法打包,兼容 99% 以上的浏览器,包括 chrome 49

在性能上,其已被证明超越了 npm 上最流行的数据结构库 functional-red-black-treedenque,并且未来我们会进一步提高其性能,参考 Benchmark

在流行性上,我们向 eslint 提交了 PR 来优化其在缩进检查所消耗的时间,并得到了 eslint 组织的采纳以及 100 美元的赞助,我们将其列举在了赞助者名单中;在 npm 上,Js-sdsl 已经获得了超过 30M/month 的下载量

或许现在的成就微不足道,但未来我们会持续建设和推广,让更多的开发者接触到 Js-sdsl

主页:https://js-sdsl.org/

Js 糟糕的数据结构生态

在 Js 中,我们可以使用 Array.sliceArray.unshift 来模拟双端队列和双端链表,但是其效率是低下的,参见 stackoverflow

糟糕的时间复杂度

虽然 Array.push 是 O(1) 实现,Array.sliceArray.unshift 确是 O(n) 的,当数据量足够大的时候其性能会呈线性下降

糟糕的底层设计

由于 Js 是一门动态语言,其中的 Array 并不像 C++ 这种静态语言一样,可以拥有绝对预定义的内存空间,考虑下面这个案例

console.time('test-js-array');
const num = 1024 * 1024 * 6;
const arr = new Array(num);
for (let i = 0; i < num; ++i) arr[i] = i;
console.timeEnd('test-js-array');
// test-js-array: 11.60986328125 ms
console.time('test-js-array');
const num = 1024 * 1024 * 6;
const arr = new Array(num);
arr[arr.length + num] = 1;
for (let i = 0; i < num; ++i) arr[i] = i;
console.timeEnd('test-js-array');
// test-js-array: 619.56884765625 ms
console.time('test-js-array');
const num = 1024 * 1024 * 6;
const arr = {};
arr[arr.length + num] = 1;
for (let i = 0; i < num; ++i) arr[i] = i;
console.timeEnd('test-js-array');
// test-js-array: 81.559814453125 ms

可以看到,当我们直接修改数组的长度超过一定限度时,修改数组的操作会变得非常慢

其原因是当我们直接操控数据长度或往数组中插入不同类型的数据后 Array 会自动降级为哈希表,并且比原生的 Object 更慢!

这对于开发者来说十分不友好,因为 Js 的类型不确定性,我们同样无法在编写时强感知数据是否会变为慢数组,导致出现一定的性能问题

部分功能的缺乏

众所周知,Js 中不含有堆和红黑树等相关功能,考虑以下情形

我有一个 JSON 数组,包含四个字段 a、b、c,其中 c 是主键,每个位置的 c 都不一样,我想根据 a、b 的值实现去重

使用 ES6.Set 会很困难,但使用 Js-sdsl 会很容易

import { OrderedSet } from 'js-sdsl';
const arr = [{ a: 1, b: 1, c: 1 }];
// 自定义排序函数实现去重
const st = new OrderedSet(arr, (x, y) => {
    if (x.a !== y.a) return x.a - y.a;
    if (x.b !== y.b) return x.b - y.b;
    return 0;
});

解决方案

为了解决上述的问题,我们提供了 Js-sdsl,一个轻量且高效的数据结构库,旨在打造完整的 Js 数据结构生态,提高开发效率以及代码性能,目前我们提供以下数据结构,未来我们会使其变得更加丰富

  • Stack - 先进后出的堆栈
  • Queue - 先进先出的队列
  • PriorityQueue - 堆实现的优先级队列
  • Vector - 受保护的数组,不能直接操作像 length 这样的属性
  • LinkList - 非连续内存地址的链表
  • Deque - 双端队列,向前和向后插入元素或按索引获取元素的时间复杂度为 O(1)
  • OrderedSet - 由红黑树实现的排序集合
  • OrderedMap - 由红黑树实现的排序字典
  • HashSet - 参考 ES6 Set polyfill 实现的哈希集合
  • HashMap - 参考 ES6 Set polyfill 实现的哈希字典
 相关资料
  • 本文向大家介绍PHP SPL标准库之数据结构栈(SplStack)介绍,包括了PHP SPL标准库之数据结构栈(SplStack)介绍的使用技巧和注意事项,需要的朋友参考一下 栈(Stack)是一种特殊的线性表,因为它只能在线性表的一端进行插入或删除元素(即进栈和出栈) SplStack就是继承双链表(SplDoublyLinkedList)实现栈。 类摘要如下: 简单使用如下:

  • 本文向大家介绍javascript标准库(js的标准内置对象)总结,包括了javascript标准库(js的标准内置对象)总结的使用技巧和注意事项,需要的朋友参考一下 值属性 这部分属性只是简单的值,它们没有自己的属性和方法。 Infinity 全局属性 Infinity 是一个数值,表示无穷大。 NaN 全局属性 NaN 的值表示不是一个数字(Not-A-Number)。 undefined 全

  • 整理一份简单易懂的关于 JS 数据结构与算法 的笔记,设计模式包括单例模式、观察者模式、代理模式、装饰器模式、委托模式、原型模式。

  • 实际上,我是使用Maven和spring的新手,我很好奇我们是如何标准化项目结构的。正如我们所知,如果我们第一次创建Maven项目,它只给出了这样的结构: 我明白,Java目录是我们放Java代码的目录。但是,当我们制作一个应该有HTML、CSS或Javascript等web文件的web应用程序时,我们需要另一个目录来放置它。 当我在Maven中使用spring或spring boot时,它也在主

  • 本文向大家介绍PHP SPL标准库之数据结构堆(SplHeap)简单使用实例,包括了PHP SPL标准库之数据结构堆(SplHeap)简单使用实例的使用技巧和注意事项,需要的朋友参考一下 堆(Heap)就是为了实现优先队列而设计的一种数据结构,它是通过构造二叉堆(二叉树的一种)实现。根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。二叉堆还常用于排序(堆排序)。 如下:最小堆(任

  • 我是Java EE的初学者,我在参考资料中读到Java EE的标准目录结构是这样的: 但当我在intellij idea中创建一个新项目时,目录结构是这样的: 现在我因为一些原因感到困惑。

  • PHPSSO 数据库结构[更新日期:2010-12-28] 点击查看 PHPCMS 数据库结构[更新日期:2010-12-28] 点击查看

  • 顺序结构 顺序栈(Sequence Stack) SqStack.cpp 顺序栈数据结构和图片 typedef struct { ElemType *elem; int top; int size; int increment; } SqStack; 队列(Sequence Queue) 队列数据结构 typedef struct { ElemType * elem; int fron