详解关于JSON.parse()和JSON.stringify()的性能小测试

JSON.parse(JSON.stringify(obj))我们一般用来深拷贝,其过程说白了,就是利用 JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反序列化(还原)js对象。至于这行代码为什么能实现深拷贝,以及它有什么局限性等等,不是本文要介绍的。本文要探究的是,这行代码的执行效率如何?如果随意使用会不会造成一些问题?

先上两个js性能测试的依赖函数

/**
 * 一个简单的断言函数
 * @param value {Boolean} 断言条件
 * @param desc {String} 一个消息
 */
function assert(value, desc) {
  let li = document.createElement('li');
  li.className = value ? 'pass' : 'fail';
  li.appendChild(document.createTextNode(desc));
  document.getElementById('results').appendChild(li);
}
/**
 * 一个测试套件,定时器是为了多次执行减少误差
 * @param fn {Function} 需要多次执行的代码块(需要测试、比对性能的代码块)
 * @param config {Object} 配置项,maxCount: 执行代码块的for循环次数,times: 定时器执行次数
 */
function intervalTest(fn, config = {}) {
  let maxCount = config.maxCount || 1000;
  let times = config.times || 10;
  let timeArr = [];
  let timer = setInterval(function () {
    let start = new Date().getTime();
    for (let i = 0; i < maxCount; i++) {
      fn.call(this);
    }
    let elapsed = new Date().getTime() - start;
    assert(true, 'Measured time: ' + elapsed + ' ms');
    timeArr.push(elapsed);
    if (timeArr.length === times) {
      clearInterval(timer);
      let average = timeArr.reduce((p, c) => p + c) / times;
      let p = document.createElement('p');
      p.innerHTML = `for循环:${maxCount}次,定时器执行:${times}次,平均值:${average} ms`;
      document.body.appendChild(p);
    }
  }, 1000);
}

定义一些初始数据

let jsonData = {
  title: 'hhhhh',
  dateArr: [],
  series: [
    {
      name: 'line1',
      data: []
    },
    {
      name: 'line2',
      data: []
    },
    {
      name: 'line3',
      data: []
    },
  ]
};

let res = [
  {
    name: 'line1',
    value: 1
  },
  {
    name: 'line2',
    value: 2
  },
  {
    name: 'line3',
    value: 3
  },
];

场景1:模拟真实环境中图表数据实时更新

数据处理函数

/**
 * 处理json数据的函数。模拟真实环境中图表数据实时更新
 * @param lastData {Object} 上一次的数据
 * @param res {Array} 当前数据
 * @returns data 处理完成后的结果集
 */
function handleJsonData(lastData, res) {
  // 1. 使用 JSON.parse(JSON.stringify()) 深拷贝
  let data = JSON.parse(JSON.stringify(lastData));

  // 2. 不使用JSON序列化,直接修改参数
  // let data = lastData;

  if (data.dateArr.length > 60) {
    data.dateArr.shift();
    for (let i = 0; i < data.series.length; i++) {
      data.series[i].data.shift();
    }
  }
  data.dateArr.push(new Date().toTimeString().substr(0, 8));
  for (let i = 0; i < data.series.length; i++) {
    data.series[i].data.push(res[i].value);
  }
  return data;
}

maxCount=100

跑起来,先让maxCount=100,for循环100次

let jsonTest = function () {
  jsonData = handleJsonData(jsonData, res);
};

intervalTest(jsonTest, {maxCount: 100});

1.使用 JSON.parse(JSON.stringify()) 深拷贝 的结果:

2.不使用JSON序列化,直接修改参数 的结果:

function handleJsonData(lastData, res) {
  // 1. 使用 JSON.parse(JSON.stringify()) 深拷贝
  // let data = JSON.parse(JSON.stringify(lastData));

  // 2. 不使用JSON序列化,直接修改参数
  let data = lastData;

  // ...
}

maxCount=1000

intervalTest(jsonTest, {maxCount: 1000});

1.使用 JSON.parse(JSON.stringify()) 深拷贝 的结果:

2.不使用JSON序列化,直接修改参数 的结果:

maxCount=10000

intervalTest(jsonTest, {maxCount: 10000});

1.使用 JSON.parse(JSON.stringify()) 深拷贝 的结果:

2.不使用JSON序列化,直接修改参数 的结果:

场景2:判断一个对象是否为空对象

// 1. 使用 JSON.stringify() 判断一个对象是否为空对象
let isEmptyObject1 = function () {
  if (JSON.stringify(jsonData) === '{}') {
    // do something
  }
};

// 2. 使用 Object.keys().length 判断一个对象是否为空对象
let isEmptyObject2 = function () {
  if (Object.keys(jsonData).length === 0) {
    // do something
  }
};

只是走了一下判断条件,if内部没有执行代码

maxCount=1000

1.使用 JSON.stringify() 判断一个对象是否为空对象 的结果:

intervalTest(isEmptyObject1, {maxCount: 1000});

2.使用 Object.keys().length 判断一个对象是否为空对象 的结果:

intervalTest(isEmptyObject2, {maxCount: 1000});

maxCount=10000

1.使用 JSON.stringify() 判断一个对象是否为空对象 的结果:

2.使用 Object.keys().length 判断一个对象是否为空对象 的结果:

maxCount=100000

1.使用 JSON.stringify() 判断一个对象是否为空对象 的结果:

2.使用 Object.keys().length 判断一个对象是否为空对象 的结果:

关于JSON.parse()和JSON.stringify()的测试先到此为止,变换参数、更改执行的代码块可能会有不同结果,以上结果仅供参考。

小结论:能不用JSON.parse()和JSON.stringify()就不用,采用替代方案且性能更优的。PS:特别是需要多次执行的代码块,特别是这个JSON数据比较庞大时

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2019-03-12

C#网络请求与JSON解析的示例代码

最新学校的海康摄像头集控平台(网页端)不能在win10里登录,我寻思着拿海康的c# demo直接改. 首先得解决权限问题,每个教师任教不同年级,只能看到自己所在年级的设备,涉及到登录,在此记录一下C#中网络请求和数据处理的一些内容.大致流程为: 客户端发起登录请求: 服务端验证账号密码 返回json字符串,包含用户信息.平台配置等信息 客户端解析并初始化 一.发起GET请求 private string HttpGet(string api) { string serviceAddress =

Android判断json格式将错误信息提交给服务器

开发中发现, 服务器偶尔会发送错误格式 json 给 Android 客户端, 导致 Android 客户端 json解析失败, 应用异常. 并非服务器有意坑客户端, 而是客户端请求服务器数据时, 除了得到正确 json 数据外, 数据可能还夹杂其它数据. 例如:  thinkPHP 开启  'SHOW_PAGE_TRACE '=> true 时, 正确的 json 后面会夹杂HTML代码, 解决办法: 1. 将 'SHOW_PAGE_TRACE ' =>false   , 设置为false.

使用post方法实现json往返传输数据的方法

问题所在: 当我们想让应用层和http之间的所有接口都采用json,这样,客户端代码就可以纯碎用javascript的对象来编写,服务器打啊也可以纯粹的用Java的对象来编写. 我们使用的是post请求的方法,有些不同于get的方法! 客户端html代码: <html> <head> <title>Hello Ajax version 5a</title> <style type='text/css'> * { font-family: Taho

详解JSON和JSONP劫持以及解决方法

json劫持 json劫持攻击又为"JSON Hijacking",攻击过程有点类似于csrf,只不过csrf只管发送http请求,但是json-hijack的目的是获取敏感数据. 一些web应用会把一些敏感数据以json的形式返回到前端,如果仅仅通过cookie来判断请求是否合法,那么就可以利用类似csrf的手段,向目标服务器发送请求,以获得敏感数据. 比如下面的链接在已登录的情况下会返回json格式的用户信息: http://www.test.com/userinfo 攻击者可以在

Python JSON格式数据的提取和保存的实现

环境:python-3.6.5 JSON JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它使得人们很容易的进行阅读和编写.同时也方便了机器进行解析和生成.适用于进行数据交互的场景,比如网站前台与后台之间的数据交互. Python中自带了json模块,直接import json即可使用 官方文档:https://docs.python.org/3/library/json.html Json在线解析网站:https://www.json.cn/# j

vue基础之使用get、post、jsonp实现交互功能示例

本文实例讲述了vue基础之使用get.post.jsonp实现交互功能.分享给大家供大家参考,具体如下: 一.如果vue想做交互,引入: vue-resouce 二.get方式 1.get获取一个普通文本数据: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style>

Java中json与javaBean几种互转的讲解

一.java普通对象和json字符串的互转 java对象---->json 首先创建一个java对象: public class Student { //姓名 private String name; //年龄 private String age; //住址 private String address; public String getName() { return name; } public void setName(String name) { this.name = name; }

MySQL5.7中的JSON基本操作指南

前言 因为项目需要,存储字段存储成了JSON格式,在项目中是将查询出来的值通过jackson转成相应的bean进行处理的,觉得不够简单方便. MySQL从5.7版本开始就支持JSON格式的数据,操作用起来挺方便的. 建表 在新建表时字段类型可以直接设置为json类型,比如我们创建一张表: mysql> CREATE TABLE `test_user`(`id` INT PRIMARY KEY AUTO_INCREMENT, `name` VARCHAR(50) NOT NULL, `info`

SpringMVC接收与响应json数据的几种方式

前言 前后端的数据交互,除了通过form表单进行提交外,也可以通过ajax向后端传递和接收json格式数据(这种方式可以实现请求数据和页面分离).本文将总结一下在Spring MVC中接收和响应json数据的几种方式. 话不多说了,来一起看看详细的介绍吧 准备步骤: 1.导入json相关框架的依赖(比如jackson). 2.spring mvc的controller方法正常写,如果需要响应json,增加@responsebody注解. 3.在接受json对应的输入参数前,加上@RequestB

微信小程序使用wx.request请求服务器json数据并渲染到页面操作示例

本文实例讲述了微信小程序使用wx.request请求服务器json数据并渲染到页面操作.分享给大家供大家参考,具体如下: 微信小程序的数据总不能写死吧,肯定是要结合数据库来做数据更新,而小程序数据主要是json数据格式,所以我们可以利用php操作数据库,把数据以json格式数据输出即可.现在给大家讲一下,微信小程序的wx.request进行服务器数据请求的用法: 官方文档给出了示例代码,但是我这边自己进行了简单的处理: index.js Page({ data: { }, onLoad: fun

小程序封装wx.request请求并创建接口管理文件的实现

开发小程序,封装有一个简单易用wx.request请求还是很必要的,可以省去大量的维护成本!闲话不多说,直接撸代码. 流程 创建http.js文件,封装wx.request 创建api.js文件,统一管理所有接口 在index.js中调用接口 创建http.js文件,封装wx.request 在utils中创建http.js文件,封装http,代码如下: module.exports = { http(url, method, params) { let token = 'token' // 获

微信小程序访问node.js接口服务器搭建教程

前言 最近在做微信的应用号小程序开发,小程序的后台数据接口需要https安全请求,所以需要我的nodejs服务器能够提供https的支持,现在就将整个https服务器的搭建过程说一下. 搭建教程如下: 首先,我试了一下以前的过期的证书,在开发者工具里模拟的时候可以正常访问接口,在手机里测试时候微信小程序的wx.request是会报SSL握手失败的错误(request error : request: fail ssl hand shake error),所以只能重新申请一个证书,这里推荐使用阿里

微信小程序 网络API发起请求详解

微信小程序 网络API: 微信小程序 网络API发起请求 微信小程序 网络API 上传.下载 微信小程序 网络API Websocket 微信小程序 wx.request(OBJECT) ​ wx.request发起的是https请求.一个微信小程序,同时只能有5个网络请求连接. OBJECT参数说明: 参数名 类型 必填 说明 url String 是 开发者服务器接口地址 data Object.String 否 请求的参数 header Object 否 设置请求的header , hea

微信小程序封装的HTTP请求示例【附升级版】

本文实例讲述了微信小程序封装的HTTP请求.分享给大家供大家参考,具体如下: 微信小程序里自己封装了请求的函数,但几乎每个页面都要用到,所以为什么更方便的调用,再一次进行封装. 在app.js里面定义个全局对象,这样想要用到该函数,只需要在该页面的js文件里面,请求一个app实例. 废话不多说,先上代码: //全局对象httpClient httpClient:{ request:function(method,url,data){ //返回一个promise实例 return new Prom

微信小程序 es6-promise.js封装请求与处理异步进程

微信小程序 es6-promise.js封装请求与处理异步进程 下载es6-promise.js置于根目录下的libs文件夹下: 在根目录utils文件夹下新建httpsPromisify.js,即定义封装请求的方法 var Promise = require('../libs/es6-promise.min') function httpsPromisify(fn) { return function (obj = {}) { return new Promise((resolve, reje

微信小程序出现wx.getLocation再次授权问题的解决方法分析

本文实例讲述了微信小程序出现wx.getLocation再次授权问题的解决方法.分享给大家供大家参考,具体如下: 首先,在page外定义一个公共函数用于发送获取位置的请求 var getLocation = function (that) { wx.getLocation({ type: 'wgs84', success: function (res) { // 经纬度 var latitude = res.latitude var longitude = res.longitude var a

微信小程序实现打开并下载服务器上面的pdf文件到手机

谈一谈ios的bug: 关于ios系统的bug这块也是快把柚子给逼疯了啊,ios系统是没有文件管理的,柚子用了很多办法,最后终于确定不管用什么办法ios都是实现不了下载的,只能实现在线查看.所以没办法,如果不考虑兼容ios的话,是很简单就能解决的,但是我想没有哪一个小程序会不让你兼容ios的吧! 先看一下不兼容ios系统的下载柚子是怎么实现的吧: 首先我们需要在页面里写入一个按钮,用来触发pdf的打开和下载,写上点击事件 //查看并下载 See_download() { wx.downloadF

微信小程序调用wx.getImageInfo遇到的坑解决

这几天做到微信小程序详情页分享的功能,需要把原页面的一些参数带到分享页,然后在分享页需要获取图片的宽高等基本信息. 1.先说分享传参的方式: 在onShareAppMessage方法里面返回的path里面可以带参数传过去,具体传参的方式有两种,一种是可以传对象(需要把JSON对象stringiny),另外一种是通过一般的参数拼接的方式一个个拼. 代码: onShareAppMessage: function (res) { let data = this.data; let shareParam

微信小程序 消息推送php服务器验证实例详解

微信小程序 消息推送php服务器验证实例详解 微信文档(靠下有个"接入指引"):https://mp.weixin.qq.com/debug/wxadoc/dev/api/custommsg/callback_help.html 设置页面("设置">>"开发设置"): https://mp.weixin.qq.com/wxopen/initprofile?action=home&lang=zh_CN 1.设置服务器域名 比如: