在Common Lisp中用独立包充当哈希表是否可行?有何优劣?
用独立包存储符号模拟哈希表是否可行?
是否可以在独立于项目包的专用包中存储大量符号,将其当作哈希表(用符号作为键来表示集合成员关系)供项目访问?
代码示例
* (defpackage :project (:use :cl)) #<PACKAGE "PROJECT"> * (defpackage :temp (:use :cl)) #<PACKAGE "TEMP"> * (in-package :project) #<PACKAGE "PROJECT"> * (intern "ABC" :temp) TEMP::ABC NIL * (find-symbol "ABC" :temp) TEMP::ABC :INTERNAL ;The following is not needed for this project, but is available * (setf (symbol-value (find-symbol "ABC" :temp)) 123) 123 * (symbol-value (find-symbol "ABC" :temp)) 123
这种方式看似可行,但有没有充分理由应该避免这么做,转而使用标准哈希表?我最初的想法是避免项目包被大量杂项键符号充斥——这些符号会在运行时由字符串生成(用于检查集合成员),涉及在运行时intern大量可能存在或不存在于"表"中的符号。我还想知道find-symbol是否比gethash更高效。另外,我也可以使用基于equal的字符串哈希表,但大量查找场景下似乎eq比对equal更合适。
补充测试:equal哈希表 vs 包符号查找的性能对比
哈希表测试代码
* (defun random-string (n) "Generate a random string of length n." (let ((charset "ABCDEFGHIJKLMNOPQRSTUVWXYZ")) (iter (repeat n) (collect (char charset (random (length charset))) result-type string)))) RANDOM-STRING * (defparameter *ht* (make-hash-table :test #'equal :size 10000)) *HT* * (iter (for i from 0 to 5000) (setf (gethash (random-string 5) *ht*) t)) NIL * (time (dotimes (i 1000000) (gethash (random-string 5) *ht*))) Evaluation took: 0.150 seconds of real time 0.109375 seconds of total run time (0.109375 user, 0.000000 system) 72.67% CPU 541,959,942 processor cycles 127,937,760 bytes consed
包查找测试代码
* (defpackage :temp1) #<PACKAGE "TEMP1"> * (iter (for i from 0 to 5000) (intern (random-string 5) :temp1)) NIL * (time (dotimes (i 1000000) (find-symbol (random-string 5) :temp1))) Evaluation took: 0.224 seconds of real time 0.171875 seconds of total run time (0.156250 user, 0.015625 system) [ Run times consist of 0.015 seconds GC time, and 0.157 seconds non-GC time. ] 76.79% CPU 807,944,162 processor cycles 127,954,624 bytes consed
测试结果
测试显示,使用equal哈希表的查找速度比包符号查找快约1.5倍。
内容的提问来源于stack exchange,提问作者davypough
相关产品推荐
相关产品推荐

