关于对象创建的Node.js JSON.parse与getter属性

时间:2015-09-30 10:51:36

标签: javascript mysql json node.js coffeescript

这主要是我做得对吗/我怎样才能做得更好' 这类话题,最后还有一些具体的问题。如果您对下面的文本有其他建议/评论,即使我没有特别提出这些问题,请随时发表评论。

我的应用程序用户有一个MySQL表,除了一组固定列外,还有一个包含JSON配置对象的文本列。这是为了存储无法存储在单独列中的变量配置数据,因为它对每个用户具有不同的属性。在配置数据上不需要任何查找/排序/任何内容,所以我们认为这是最好的方法。

从我的Node.JS应用程序查询数据库(在节点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事件循环,而config属性只需要大约一半的时间(这是一个快速服务器的中间件函数)所以这样JSON只会在解析时解析它实际上是需要的。配置数据本身可以在几个嵌套对象中组织5到50个不同的属性,而不是大量的数据,但仍然不仅仅是几行JSON。

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

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

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

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

  • 现在,三个JSON数据集来自SQL查询中的两个不同的表。这只需要为每个请求执行一次查询,而不是最多四次。请记住,有些情况下不需要所有JSON数据,而且还需要所有三个数据集的场景(当然还有其中的场景),只能从其表中获取所需的JSON数据,在实际需要其中一个数据集时?我避免这种情况,因为我觉得等待执行四个单独的SELECT查询需要的时间比等待一个带有两个JOINed表的查询要长。

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

注意:当我说性能时,它主要意味着快速有效的吞吐率。我们更喜欢比较重的CPU使用量更大的内存占用。

1 个答案:

答案 0 :(得分:1)

  

我们应该忘记效率低,大约97%的时间说:   过早优化是万恶之源      - 唐纳德克努特

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

JSON.parse阻止了事件循环,但是每次同步调用都是这样 - 这只是代码执行并不是坏事。

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

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

当优化的时候,我会看看你的懒惰初始化做MySQL调用。配置只需要50%的时间,它不会阻止事件循环,而外部调用db绝对会使JSON.parse()相形见绌。

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

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

查看this site以获取提示。

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

恕我直言:无关紧要

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

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

Q4 是否还有其他方法可以改善整体效果?

无法分辨。开始的地方是观察到的行为,然后是分析器工具来识别罪魁祸首,然后进行代码优化。