首页 > 其他分享 >Proxy 的 性 能 可 能 比 defineProperty 更 差

Proxy 的 性 能 可 能 比 defineProperty 更 差

时间:2024-03-05 16:59:36浏览次数:25  
标签:count index target Proxy defineProperty now

老有人跑来跟我说 Proxy 和 defineProperty 相比,是性能的巨大提升。我一听,这不对劲啊,跟我学的知识不太一样,我明明记得Proxy 性能比 defineProperty 更差。

所以我就写了几个简单的例子来验证一下。

这个例子的逻辑非常简单,我们在大数据量循环的过程中,分别用 Object.defineProperty 与 Proxy 劫持的数据,执行一次 getter 与 setter。然后利用 performance.now 记录执行时间。

先看 defineProperty 的案例。

首先定义一个简单对象

// 在循环中,我们会执行计算操作
var target = {
  total: 0
}

然后另外定义一个普通变量用于存储劫持过程中访问和设置的值。

然后用 Object.defineProperty 劫持 target。

Object.defineProperty(target, 'count', {
  get: function () {
    return b;
  },
  set: function (value) {
    b = value;
  },
});

然后循环 1000000 次,并打印执行时间

var total = 0;
var now = performance.now()
for (let index = 0; index < end; index++) {
  total += target.count;
  target.count = index;
}
console.log('defineProperty', performance.now() - now)

接下来看使用 Proxy 的案例。

也是首先定义一个普通对象

var target = {
  count: 0
}

然后使用 Proxy 代理。

let proxy = new Proxy(target, {
  get: (target, prop, receiver) => {
    return Reflect.get(target, prop, receiver)
  },
  set(target, prop, value) {
    return Reflect.set(target, prop, value)
  }
});
 

然后循环访问 getter 和 setter

var total = 0;
var now = performance.now()
for (let index = 0; index < end; index++) {
  total += proxy.count;
  proxy.count = index;
  proxy.count
}
console.log('Proxy', performance.now() - now)
 

完整代码如下

<script>
var end = 1000000
var b = 0;
var target = {
  count: 0
}

Object.defineProperty(target, 'count', {
  get: function () {
    return b;
  },
  set: function (value) {
    b = value;
  },
});
var total = 0;
var now = performance.now()
for (let index = 0; index < end; index++) {
  total += target.count;
  target.count = index;
}
console.log('defineProperty', performance.now() - now)
</script>
<script>
var end = 1000000
var target = {
  count: 0
}

let proxy = new Proxy(target, {
  get: (target, prop, receiver) => {
    return Reflect.get(target, prop, receiver)
  },
  set(target, prop, value) {
    return Reflect.set(target, prop, value)
  }
});

var total = 0;
var now = performance.now()
for (let index = 0; index < end; index++) {
  total += proxy.count;
  proxy.count = index;
}
console.log('Proxy', performance.now() - now)
</script>

 

测试的浏览器都是最新版。因此这里我们都定义的是 1000000 万次的执行,以更加方便的放大差异。

理论上绝大多数客户的电脑性能都很差,特别是许多面向 B 端的客户,所以如果有条件的朋友可以用客户的环境来做一下测试看看客户电脑上的真实差异

在 chrome 中执行结果为:

 

我连续执行了 10 次,发现执行结果都相差不大,执行时间上,Proxy 用时更久

然后我切换浏览器,在 safari 中执行同样的代码,执行结果如下:

 

结果没想到,在 safari 浏览器中,Proxy 的性能严重低于 defineProperty.

然后我又把代码发给群友,群友用 QQ 浏览器执行了一下

 

万万没想到的是,firefox 的执行结果差异最大。

 

然后我又尝试让 Proxy 代理的对象增加层级,然后进行 set 操作

注意,这里只是简单的增加对象复杂度,并不代表更深层级的属性也能被代理。

var target = {
  count: 0,
  b: {
    c: 0
  }
}
for (let index = 0; index < end; index++) {
  total += proxy.count;
  proxy.count = index;
  proxy.b.c = target.count
}

 

验证结果发现,当层级变深,执行消耗的时间越长。下图是 chrome 的执行结果。

 

结论

在常用的几种浏览器中,测试结果比较统一,Proxy 的性能都弱于 defineProperty,在 safari,firefox 中,defineProperty 的性能大幅度领先。

当 Proxy 的目标对象深层次 getter/setter 时,会增加更多的性能损耗。

针对 Proxy 的性能,chrome 优化做得最好。但依然小幅度弱于 defineProperty

针对于 defineProperty 的性能,firefox 和 safari 做得比较好,大幅度领先其他浏览器。

 

 

标签:count,index,target,Proxy,defineProperty,now
From: https://www.cnblogs.com/zengxuelan/p/18054379

相关文章

  • 变量$host、$http_host、$proxy_host区别
    //如果想让Host是crmtest.aty.sohuno.com,则进行如下设置:proxy_set_headerHostcrmtest.aty.sohuno.com;//如果不想改变请求头“Host”的值,可以这样来设置:proxy_set_headerHost$http_host;//但是,如果客户端请求头中没有携带这个头部,那么传递到后端服务器的请求也不含这个头......
  • Kubelet安装时子节点出现:kube-proxy-7jxg4 ContainerCreating
    一般分为两种情况主节点问题和kube-proxy问题:1、查看报错:kubectldescribepodkube-proxy-7jxg4-nkube-system2、子节点查看相关报错信息journalctl-ukubelet-f可以看出是创建容器失败:1、可能是docker镜像没有导入2、网络问题,重启看一下cri-docker是否有报错信息......
  • FRP(Fast Reverse Proxy)网络映射工具部署
    FastReverseProxy(FRP)是一款由fatedier开发的高性能的反向代理工具,用于穿透防火墙、NAT等网络障碍,将内网服务映射到公网上github地址https://github.com/fatedier/frp 下载https://github.com/fatedier/frp/releases根据操作系统找到对应版本,客户端服务端共用一个包。 ......
  • 【APP逆向18】解决NO_PROXY抓包问题
    1.前置:在抓包某货app时,基于关键字搜索,我们发现抓不到返回商品信息的接口,这是怎么回事呢?这是因为在安卓开发时,OkHttp发送请求,设置Proxy.NO_PROXY,基于系统代理都是抓不到包。OkHttpClientclient=newOkHttpClient();FormBodyform=newFormBody.Builder().add("user"......
  • nginx 反向代理proxy_pass, 同一个端口多个域名的问题
    案例:serverip1:1.2.3.4domain1:aa.com>>指向ip1,port80domain2:bb.com>>指向ip1,port80serverip2:2.2.3.4domain3:cc.com>>指向ip3配置nginx转发到aa.com域名下的服务则需要做如下配置:location/{proxy_set_headerHostaa.com......
  • 教你如何用Keepalived和HAproxy配置高可用 Kubernetes 集群
    本文分享自华为云社区《使用Keepalived和HAproxy创建高可用Kubernetes集群》,作者:江晚正愁余。高可用Kubernetes集群能够确保应用程序在运行时不会出现服务中断,这也是生产的需求之一。为此,有很多方法可供选择以实现高可用。本教程演示了如何配置Keepalived和HAproxy......
  • mitmproxy 抓包神器-6.如何在linux操作系统中安装
    前言常见的抓包工具有fiddler和charles,这些工具都是需要安装本地客户端,python版的抓包工具可以用mitmproxy。mitmproxy相比Charles、fiddler的优点在于,它可以命令行方式或脚本的方式启动服务,跨平台使用。Linux环境安装mitmproxy(man-in-the-middleattackproxy),中间人......
  • 在K8S中,kube-proxy的工作模式是什么?
    kube-proxy在Kubernetes集群中负责实现Service的网络代理和负载均衡功能,支持三种不同的工作模式:Userspace模式(已过时):在早期的Kubernetes版本中(1.2之前),kube-proxy默认使用Userspace模式。在此模式下,kube-proxy作为一个用户空间进程运行,为每个Service创建一个......
  • Object— Object.defineProperty()(详解、原理、作用、使用场景、使用方式)
    一.Object.defineProperty()详解Object.defineProperty()是JavaScript中用于定义或修改对象的属性的方法,可以控制属性的特性(如可枚举性、可配置性、可写性等)。Object.defineProperty()方法的语法如下:Object.defineProperty(obj,prop,descriptor)obj:要在其上定义属性......
  • IfcBuildingElementProxyTypeEnum
    IfcBuildingElementProxyTypeEnum类型定义此枚举定义IfcBuildingElementProxy或IfcBuildngElementProxyType的可用泛型类型。 IFC2x3 新枚举IFC4更改枚举器PROVISIONFORVOID。DEPRECATION枚举器COMPLEX、ELEMENT、PARTIAL将不再使用。 EnumerationdefinitionConsta......