shi*_*oto 5 json go redis revel
我正在使用Go,Revel WAF和Redis.
我必须在Redis中存储大的json数据(可能是20MB).
json.Unmarshal()约需5秒钟.什么是更好的方法呢?
我尝试过JsonLib,编码/ json,ffjson,megajson,但是没有一个足够快.
我想过使用groupcache,但是Json是实时更新的.
这是示例代码:
package main
import (
"github.com/garyburd/redigo/redis"
json "github.com/pquerna/ffjson/ffjson"
)
func main() {
c, err := redis.Dial("tcp", ":6379")
defer c.Close()
pointTable, err := redis.String(c.Do("GET", "data"))
var hashPoint map[string][]float64
json.Unmarshal([]byte(pointTable), &hashPoint) //Problem!!!
}
Run Code Online (Sandbox Code Playgroud)
解析大型JSON数据似乎确实比它应该更慢.确定原因并向Go作者提交补丁是值得的.
与此同时,如果您可以避免使用JSON并使用二进制格式,那么您不仅可以避免此问题; 您还将获得代码现在花费时间将数字的ASCII十进制表示解析为其二进制IEEE 754等效值的时间(并且在执行此操作时可能会引入舍入错误.)
如果发件人和收件人都是用Go编写的,我建议使用Go的二进制格式:gob.
做一个快速测试,生成一个包含2000个条目的映射,每个条目包含1050个简单的浮点数,给我20 MB的JSON,在我的机器上解析需要1.16秒.
对于这些快速基准测试,我最好使用三次运行,但我确保只测量实际的解析时间,t0 := time.Now()在Unmarshal调用之前和time.Now().Sub(t0)之后打印.
使用GOB,相同的映射产生18 MB的数据,需要115 ms才能解析:
十分之一的时间.
您的结果将根据您拥有的实际浮动数量而有所不同.如果你的浮点数有很多有效数字,值得他们的float64表示,那么20 MB的JSON将包含比我的200万浮点数少得多的数据.在这种情况下,JSON和GOB之间的差异将更加明显.
顺便说一句,这证明问题确实存在于JSON解析器中,而不是要解析的数据量,也不存在于要创建的内存结构中(因为两个测试都在解析~20 MB的数据并重新创建相同的浮点数.)用JSON中的字符串替换所有浮点数给出了1.02秒的解析时间,确认从字符串表示到二进制浮点数的转换确实需要一定的时间(与仅移动字节相比)但不是主要的罪魁祸首.
如果发送者和解析器都不是Go,或者你想要比GOB更进一步挤出性能,你应该使用自己的自定义二进制格式,使用Protocol Buffers或手动使用"encoding/binary"和朋友.
| 归档时间: |
|
| 查看次数: |
7357 次 |
| 最近记录: |