6

最近,我需要解析 Chrome Web 浏览器在其开发工具中记录事件时生成的 JSON,并从中获取一些计时数据。Chrome 可以在很短的时间内生成大量数据,所以我最初构建的 Ruby 解析器非常慢。

由于我正在学习 Go,我决定用 Go 和 JavaScript/Node 编写脚本并进行比较。

JSON 文件的最简单形式就是我在这个 Gist中所拥有的。它包含一个表示为获取页面而发送的请求的事件,以及一个表示响应的事件。通常,需要筛选大量额外数据这是它自己的问题,但不是我在这个问题上担心的问题。

我写的 JavaScript 脚本在这里,我写的 Go 程序在这里。这是我用 Go 写的第一个有用的东西,所以我敢肯定它很糟糕。但是,我注意到的一件事是它在解析大型 JSON 文件时比 JavaScript 慢得多

在 Go 中使用 119Mb JSON 文件的时间:

$ time ./parse data.json
= 22 Requests
  Min Time:      0.77
  Max Time:      0.77
  Average Time:  0.77
./gm data.json  4.54s user 0.16s system 99% cpu 4.705 total

在 JavaScript/Node 中使用 119Mb JSON 文件的时间:

$ time node parse.js data.json
= 22 Requests
  Min Time: 0.77
  Max Time: 0.77
  Avg Time: 0.77
node jm.js data.json  1.73s user 0.24s system 100% cpu 1.959 total

(在这个例子中,最小/最大/平均时间都是相同的,因为我复制了 JSON 对象以便拥有一个非常大的数据集,但这无关紧要。)

我很好奇是否只是 JavaScript/Node 在解析 JSON 时速度更快(我猜这不会特别令人惊讶),或者如果我在 Go 程序中做错了什么。我也只是好奇我在 Go 程序中做错了什么,因为我确信它有很多错误。

请注意,虽然这两个脚本所做的不仅仅是解析,但在 Go 中肯定会 json.Unmarshal()在程序中增加大量时间。

更新

我添加了一个Ruby 脚本

$ ruby parse.rb
= 22 Requests
  Min Time: 0.77
  Max Time: 0.77
  Avg Time: 0.77
ruby parse.rb  4.82s user 0.82s system 99% cpu 5.658 total
4

1 回答 1

10

使用 Go,您可以将 JSON 解析为静态类型的结构。使用 JS 和 Ruby,您可以将其解析为哈希表。

为了将 JSON 解析为您定义的结构,json 包需要找出其字段的名称和类型。为此,它使用了反射包,它比直接访问这些字段要慢得多。

根据您在解析数据后对数据所做的处理,额外的解析时间可能会收回成本。Go 数据结构使用的内存比哈希表少,而且访问速度要快得多。因此,如果您对数据进行大量处理,则节省的处理时间可能会超过额外的解析时间。

于 2013-07-11T23:44:52.600 回答