javascript localStorage 的速度/成本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8074218/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 02:10:23  来源:igfitidea点击:

Speed/cost of localStorage

javascripthtmllocal-storage

提问by Mike

How fast is looking up a value in localStorage with Javascript?

使用 Javascript 在 localStorage 中查找值的速度有多快?

Does anyone have links to any performance tests that indicate whether or not it is worth caching the data in a JavaScript object? Or does the browser already cache values that are accessed from localStorage anyway?

有没有人有任何性能测试的链接,表明是否值得在 JavaScript 对象中缓存数据?或者浏览器是否已经缓存了从 localStorage 访问的值?

I am particularly interested in Firefox and Chrome implementations of localStorage.

我对 localStorage 的 Firefox 和 Chrome 实现特别感兴趣。

采纳答案by Mike

For what it's worth, here is a jsperf test.

对于它的价值,这里是一个jsperf 测试

The benchmark usage of localStorageis significantly slowerthan access of a regular object propertiesin both FF7 and IE9. Of course, this is just a micro-benchmark, and does not necessarily reflect real-world usage or performance...

的基准使用localStorage显著慢比的访问规则对象属性在两个FF7和IE9。当然,这只是一个微基准,并不一定反映现实世界的使用或性能......

Sample pulled from my FF 7 run to show what "significantly slower" means, in ops/second:

从我的 FF 7 运行中提取的样本以显示“显着慢”的含义,以操作数/秒为单位:

            native     local-storage    notes
small set   374,397    13,657           10 distinct items
large set   2,256      68               100 distinct items
read-bias   10,266     342              1 write, 10 reads, 10 distinct items

Also, there are restrictions on what can be put in localStorage. YMMV.

此外,对可以放入 localStorage 的内容也有限制。天啊。

回答by Lukas Liesis

Just made a small benchmark. What i plan to do is to get some data from localStorage quite often and i wondered will it block. While localStorage.getItem is synced operation it may sound scary but is it?

只是做了一个小基准。我打算做的是经常从 localStorage 获取一些数据,我想知道它会阻塞。虽然 localStorage.getItem 是同步操作,但它可能听起来很可怕,但是是吗?

  • 1st test to call 1 million times localStorage to get item which does exist.
  • 2nd test to call 1 million times localStorage to get item which does NOT exist.
  • 第一次测试调用 100 万次 localStorage 以获取确实存在的项目。
  • 第二次测试调用 100 万次 localStorage 以获取不存在的项目。

Results:

结果:

"Item found: 0.0007991071428571318ms per call"

"Item not found: 0.0006365004639793477ms per call"

“找到的项目:每次调用 0.0007991071428571318ms”

“未找到项目:每次调用 0.0006365004639793477ms”

In short - just use it. It takes no time. 0.0007 of 1 millisecond.

简而言之 - 只需使用它。不需要时间。1 毫秒的 0.0007。

https://jsbin.com/resuziqefa/edit?js,console

https://jsbin.com/resuziqefa/edit?js,console

 let results = [];
 let sum = 0;
 localStorage.setItem('foo', 'foo bar baz foo bar baz foo bar baz foo');

 for (let i = 0; i < 1000000; i++) {
   let a = performance.now();
   localStorage.getItem('foo');
   let result = performance.now() - a;
   sum += result;
   results.push(result);
 }

 console.log(`Item found: ${sum / results.length}ms per call`);

 results = [];
 sum = 0;
 for (let i = 0; i < 1000000; i++) {
   let a = performance.now();
   localStorage.getItem('bar');
   let result = performance.now() - a;
   sum += result;
   results.push(result);
 }

 console.log(`Item not found: ${sum / results.length}ms per call`);

回答by cchamberlain

Apples to apples

苹果对苹果

There is not much value in comparing localStorageto object storage, the two have different purposes in JavaScript. It is likely that you will only need to touch localStoragea few times in your app and the rest of the work will be done in memory.

localStorage与对象存储相比没有太大的价值,两者在 JavaScript 中有不同的用途。很可能你只需要localStorage在你的应用程序中触摸几次,其余的工作将在内存中完成。

Local Storage vs Cookies

本地存储与 Cookie

A better comparison against localStoragewould be that of its classic counterpart, document.cookie. Both localStorageand document.cookie's main purpose is to persist a value across browser refreshes.

一个更好的比较localStorage是它的经典对应物,document.cookie. 这两个localStoragedocument.cookie的主要目的是坚持跨浏览器刷新的值。

I've put together an example on codsandbox.io

我在codsandbox.io上放了一个例子

  • localStorageis two orders of magnitude faster than document.cookie.
  • Objectstorage is an order of magnitude faster than localStorage(irrelevant but added for reference).
  • localStorage比 快两个数量级document.cookie
  • Object存储比localStorage(无关但添加以供参考)快一个数量级。

localStorageis by far the fastest mechanism to persist values across a browser refresh.

localStorage是迄今为止在浏览器刷新中保持值的最快机制。

localstoragevcookies

localstoragevcookies

Note that I've precompiled cookie regex getters in order to make cookies as fast as possible and used the browser performance API for accurate measurements. All tests do a set of a unique key followed by a get of the same key.

请注意,我已经预编译了 cookie regex getter 以便尽可能快地制作 cookie,并使用浏览器性能 API 进行准确测量。所有测试都执行一组唯一键,然后获取相同的键。

回答by alextes

I appreciate the efforts of the previous answers but found the benchmarks lacking. Here's a better micro-benchmark, do note, it's still a micro-benchmark. Always prefer measuring real performance bottlenecks to doing premature performance optimization.

我感谢先前答案的努力,但发现缺乏基准。这是一个更好的微基准,请注意,它仍然是一个微基准。与过早进行性能优化相比,始终更喜欢测量实际性能瓶颈。

Benchmarks are for reading and writing a single value, a list of a hundred objects, and a list of ten-thousand objects from and to localStorage.

基准测试用于从 localStorage 读取和写入单个值、一百个对象的列表以及一万个对象的列表。

TL;DR:

特尔;博士:

single read: 0.0004ms, write: 0.0114ms
small list read: 0.0325ms, write: 0.0498ms
large list read: 3.1787ms, write: 3.3190ms

Ran on a 3,1 GHz Quad-Core Intel Core i7. Chrome 79.

在 3,1 GHz 四核 Intel Core i7 上运行。铬 79。

read local storage - single x 2,439,715 ops/sec ±0.91% (62 runs sampled)
read local storage - small x 30,742 ops/sec ±0.78% (62 runs sampled)
read local storage - large x 315 ops/sec ±1.30% (60 runs sampled)
write local storage - single x 88,032 ops/sec ±4.25% (33 runs sampled)
write local storage - small x 20,079 ops/sec ±1.89% (59 runs sampled)
write local storage - large x 301 ops/sec ±1.09% (60 runs sampled)

Test: read local storage - single
mean: 0.0004098839352502669ms
margin of error: ±0.000003731514453196282ms
devation: ±0.00001499080315635531ms

Test: read local storage - small
mean: 0.03252840093744983ms
margin of error: ±0.0002551322114660716ms
devation: ±0.001024955633672395ms

Test: read local storage - large
mean: 3.1786666666666674ms
margin of error: ±0.041479799689699ms
devation: ±0.16392915653288143ms

Test: write local storage - single
mean: 0.011359496605398242ms
margin of error: ±0.00048286808926899016ms
devation: ±0.0014152377493978731ms

Test: write local storage - small
mean: 0.04980309857651518ms
margin of error: ±0.0009408982120607311ms
devation: ±0.0036873348473201325ms

Test: write local storage - large
mean: 3.31899154589372ms
margin of error: ±0.03605551145015122ms
devation: ±0.14249224018921072ms

Here's a snippet to run it yourself if you wish.

如果您愿意,这里有一个片段可以自己运行它。

<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.min.js"></script>
<script>
  const suite = new Benchmark.Suite();

  const genNum = () => Math.floor(Math.random() * 1000000);

  const genObj = () => ({
    target: String(genNum()),
    swap: String(genNum()),
    price: genNum()
  });

  const printStats = test =>
    console.log(
      `Test: ${test.name}
mean: ${test.stats.mean * 1000}ms
margin of error: ±${test.stats.moe * 1000}ms
devation: ±${test.stats.deviation * 1000}ms`
    );

  const singleNum = String(genNum());
  const smallList = _.range(100).map(genObj);
  const largeList = _.range(10000).map(genObj);

  const singleKey = "single-key";
  const smallKey = "small-key";
  const largeKey = "large-key";

  localStorage.setItem(singleKey, singleNum);
  localStorage.setItem(smallKey, JSON.stringify(smallList));
  localStorage.setItem(largeKey, JSON.stringify(largeList));

  suite
    .add("read local storage - single", function() {
      const readData = localStorage.getItem(singleKey);
    })
    .add("read local storage - small", function() {
      const readData = JSON.parse(localStorage.getItem(smallKey));
    })
    .add("read local storage - large", function() {
      const readData = JSON.parse(localStorage.getItem(largeKey));
    })
    .add("write local storage - single", function() {
      localStorage.setItem("single_write_key", singleNum);
    })
    .add("write local storage - small", function() {
      localStorage.setItem("small_write_key", JSON.stringify(smallList));
    })
    .add("write local storage - large", function() {
      localStorage.setItem("large_write_key", JSON.stringify(largeList));
    })
    .on("cycle", function(event) {
      console.log(String(event.target));
    })
    .on("complete", function() {
      this.forEach(printStats);
    })
    .run({ async: true });
</script>