今天偶然看了下 lsp-mode 文档,似乎能够解答这个问题。
Performance - LSP Mode - LSP support for Emacs
lsp-modecan be compiled in 2 modesplistandhash-tablebasedlsp-use-plistsflag.plists provide better performance in deserialization and also put less presure thanhash-tables.
将 JSON 解析到 plist 比 hashtable 效率更高,如果主要处理时间是解析而不是查找 plist 应该更占优势。至于解析到 plist 和 alist 的性能比较,我感觉没有明显差距。
{
"problems": [{
"Diabetes":[{
"medications":[{
"medicationsClasses":[{
"className":[{
"associatedDrug":[{
"name":"asprin",
"dose":"",
"strength":"500 mg"
}],
"associatedDrug#2":[{
"name":"somethingElse",
"dose":"",
"strength":"500 mg"
}]
}],
"className2":[{
"associatedDrug":[{
"name":"asprin",
"dose":"",
"strength":"500 mg"
}],
"associatedDrug#2":[{
"name":"somethingElse",
"dose":"",
"strength":"500 mg"
}]
}]
}]
}],
"labs":[{
"missing_field": "missing_value"
}]
}],
"Asthma":[{}]
}]}
测试代码:
(let ((gc-cons-threshold (* 1024 1024 1024)))
(benchmark-run 100000
(with-current-buffer "t"
(save-excursion
(json-parse-buffer :object-type 'alist)))))
;; hash-table (0.636845 0 0.0)
;; plist (0.3785043 0 0.0)
;; alist (0.3963708 0 0.0)
注意,plist 和 alist 均在 0.35 到 0.40 之间波动。
以下是 json_parse_object 的一部分代码:
case json_object_alist:
{
Lisp_Object key = json_parse_string (parser, true, false);
Lisp_Object value = json_parse_object_member_value (parser);
Lisp_Object nc = Fcons (Fcons (key, value), Qnil);
*cdr = nc;
cdr = xcdr_addr (nc);
break;
}
case json_object_plist:
{
Lisp_Object key = json_parse_string (parser, true, true);
Lisp_Object value = json_parse_object_member_value (parser);
Lisp_Object nc = Fcons (key, Qnil);
*cdr = nc;
cdr = xcdr_addr (nc);
nc = Fcons (value, Qnil);
*cdr = nc;
cdr = xcdr_addr (nc);
break;
}