javascript - Node.js JSON.parse 关于对象创建与使用 getter 属性

标签 javascript mysql json node.js coffeescript

这主要是一个“我做得对吗/我怎样才能做得更好” 类的主题,最后有一些具体问题。如果您对以下文本有其他建议/评论,即使我没有专门问这些问题,也请随时发表评论。


我有一个供我的应用程序用户使用的 MySQL 表,除了一组固定列外,还有一个包含 JSON 配置对象的文本列。这是为了存储可变配置数据,这些数据不能存储在单独的列中,因为它对每个用户具有不同的属性。不需要对配置数据进行任何查找/排序/任何操作,因此我们认为这是最好的方法。

当从我的 Node.JS 应用程序(在 Node 0.12.4 上运行)查询数据库时,我将 JSON 文本分配给一个对象,然后使用 Object.defineProperty 创建一个 getter 属性,当它是时解析 JSON 字符串数据需要并将其添加到对象。

代码如下所示:

user = 
    uid: results[0].uid
    _c: results[0].user_config # JSON config data as string

Object.defineProperty user, 'config',
    get: ->
        @c = JSON.parse @_c if not @c?
        return @c

编辑:上面的代码是 Coffeescript,对于那些不使用 Coffeescript 的人来说,这里是(近似)等效的 Javascript:

var user = {
    uid: results[0].uid,
    _c: results[0].user_config // JSON config data as string
};

Object.defineProperty(user, 'config', {
    get: function() {
        if(this.c === undefined){
            this.c = JSON.parse(this._c);
        }
        return this.c;
    }
});

我以这种方式实现它是因为解析 JSON 会阻塞 Node 事件循环,并且只有大约一半的时间需要配置属性(这是在 express 服务器的中间件函数中)所以这种方式只会在以下情况下解析 JSON它实际上是需要的。配置数据本身的范围可以从 5 到大约 50 个不同的属性组织在几个嵌套对象中,数据量不是很大,但仍然不仅仅是几行 JSON。

此外,还有三个这样的 JSON 对象(我只展示了一个,因为它们基本相同,只是其中的数据不同)。每个场景都需要在不同的场景中使用,但所有场景都取决于变量(其中一些来自外部源),因此在这个函数点上不可能知道哪些是必需的。

所以我有几个关于这种方法的问题,希望你们能回答。

  • 使用 Object.defineProperty 是否会对性能产生负面影响?如果是,是否有可能抵消不立即解析 JSON 数据的好处?

  • 我假设不立即解析 JSON 实际上会提高性能是否正确?我们正在处理持续不断的大量请求,我们需要快速高效地处理这些请求。

  • 现在,三个 JSON 数据集来自在 SQL 查询中联接的两个不同表。这是每个请求只需要执行一个查询,而不是最多四个。请记住,有些场景不需要任何 JSON 数据,但也有需要所有三个数据集的场景(当然还有介于两者之间的场景),仅从其表中获取所需的 JSON 数据是否是一种改进,在实际需要其中一个数据集的时候?我避免了这一点,因为我觉得等待执行四个单独的 SELECT 查询比等待一个包含两个 JOIN 表的查询花费的时间更长。

  • 是否有其他方法可以进一步提高总体性能? (我知道,这是一个有点主观的问题,但欢迎提出我应该检查的事情的想法/建议)。不过,我不打算将 JSON 数据解析到一个单独的线程中,因为当我们的服务在虚拟化单核服务器集群上运行时,创建子进程只会增加整体 CPU 使用率,这在高负载时会对性能的负面影响甚至更大。

注意:当我说性能时,它主要是指快速高效的吞吐率。我们更喜欢更大的内存占用量,而不是更重的 CPU 使用率。

最佳答案

We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil
- Donald Knuth

我从这篇文章中得到了什么?太多时间花在了优化结果可疑上,而不是专注于设计和清晰度上。

确实 JSON.parse 会阻塞事件循环,但每个同步调用都会阻塞 - 这只是代码执行,并不是坏事。

根本问题不是阻塞,而是阻塞多长时间。我记得一位 Strongloop 讲师说 10 毫秒是云规模应用程序调用最大执行时间的一个很好的经验法则。 >10 毫秒是开始优化的时间 - 对于大规模应用程序。每个应用都必须定义该阈值。

那么,你的 lazy init 会节省多少执行时间? This article表示解析一个 15MB 的 json 字符串需要 1.5 秒——大约 10,000 B/ms。 3 个配置,每个配置 50 个属性,30 字节/k-v 对 = 4500 字节 - 大约半毫秒。

当需要进行优化时,我会考虑让您的惰性 init 执行 MySQL 调用。只有 50% 的时间需要配置,它不会阻塞事件循环,并且对数据库的外部调用绝对使 JSON.parse() 相形见绌。

所有这一切都是为了说明:您所做的不一定是坏事或错误,但如果整个应用程序充斥着这些类型的可疑优化,这对功能添加和维护有何影响?我看到的最大问题是上市时间,而不是速度。代码复杂性会增加上市时间。

Q1:使用 Object.defineProperty 时是否会对性能产生负面影响...

查看 this site寻求提示。

Q2:*...不立即解析 JSON 实际上会提高性能...

恕我直言:无关紧要

Q3:现在三个 JSON 数据集来自两个不同的表...

大多数数据库查询成本通常是进程外调用和网络数据传输(除非您的架构或配置非常糟糕)。一次通话中的所有数据都是正确的举动。

Q4:是否有其他方法可以提高总体性能

无法判断。首先是观察到的行为,然后是分析器工具来识别罪魁祸首,然后是代码优化。

关于javascript - Node.js JSON.parse 关于对象创建与使用 getter 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32864233/

相关文章:

javascript - 使用map函数迭代和分组对象

php - Mysql 在同一查询中使用 AND & OR LIKE 时排除第一个参数?

mysql - 保存到数据库的日期值与应有的值不同

javascript - 如何禁用 "Save Changes"按钮直到进行更改?

javascript - 使用scrollMagic从右向左滑动动画

php - 基于 If PHP 的消息页面的标题

arrays - 用节点替换 jq 中从根开始的路径

json - 我如何检查 json 中的 key ,这是我从 RESTful api 获得的输出

javascript - Knob.js 作为 Soundmanager2 的进度条

javascript - $(window).resize 仅在浏览器刷新时触发?