You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求支持向流输出结果的Common Lisp计时功能实现方案

Common Lisp time宏输出写入文件的实现方案

Common Lisp标准中time宏的输出默认绑定到动态变量*trace-output*,不需要额外引入第三方库,通过临时重绑定该变量即可完成输出落盘,具体可按需求选择以下两种方案:

方案1:直接捕获原生time输出

如果需要保留time宏的原生输出格式,只需要在执行测试代码前把*trace-output*绑定到目标文件流即可,示例如下:

;; 将time输出追加写入time-results.txt
(with-open-file (*trace-output* "time-results.txt"
                 :direction :output
                 :if-exists :append
                 :if-does-not-exist :create)
  ;; 替换为你要测试的代码
  (time (loop for i from 1 to 1000000 sum i)))

如果需要同时在终端看到计时输出、同时写入文件,可以绑定广播流实现:

(with-open-file (file-stream "time-results.txt"
                 :direction :output
                 :if-exists :append
                 :if-does-not-exist :create)
  (let ((*trace-output* (make-broadcast-stream *standard-output* file-stream)))
    (time (loop for i from 1 to 1000000 sum i))))

方案2:自定义结构化计时输出(更适合统计分析)

如果需要后续对计时结果做批量统计、筛选,建议自定义计时宏输出结构化的CSV格式数据,避免解析原生time的非结构化文本,SBCL环境下的示例实现如下:

(defmacro time-to-csv (csv-path test-form &optional case-desc)
  "执行test-form,将计时结果按CSV格式追加写入csv-path,case-desc为测试用例说明"
  (let ((start-real (gensym))
        (start-run (gensym))
        (start-gc-time (gensym))
        (start-gc-count (gensym)))
    `(let ((,start-real (get-internal-real-time))
           (,start-run (get-internal-run-time))
           (,start-gc-time sb-ext:*gc-run-time*)
           (,start-gc-count sb-ext:*gc-count*))
       (multiple-value-prog1
           (,test-form)
         (let* ((real-sec (/ (- (get-internal-real-time) ,start-real)
                             internal-time-units-per-second))
                (run-sec (/ (- (get-internal-run-time) ,start-run)
                            internal-time-units-per-second))
                (gc-sec (/ (- sb-ext:*gc-run-time* ,start-gc-time)
                           internal-time-units-per-second))
                (gc-count (- sb-ext:*gc-count* ,start-gc-count)))
           (with-open-file (f ,csv-path
                            :direction :output
                            :if-exists :append
                            :if-does-not-exist :create)
             ;; 输出格式:用例描述, 实时时间(秒), CPU时间(秒), GC时间(秒), GC次数
             (format f "~S,~,4F,~,4F,~,4F,~D~%"
                     (or ,case-desc (prin1-to-string ',test-form))
                     real-sec run-sec gc-sec gc-count)))))))

;; 使用示例
(time-to-csv "benchmark-results.csv" (loop for i from 1 to 1000000 sum i) "百万序列求和测试")

生成的CSV文件可以直接用Excel、Python pandas等工具导入做聚合统计、排序筛选。

注意事项

  • 绝大多数主流Common Lisp实现(SBCL、CCL、ABCL等)的time宏输出都绑定*trace-output*,小众实现如果不生效,可以查询对应实现的文档确认time的输出目标流变量。
  • 自定义计时宏中的GC相关接口是SBCL专属,其他实现可以替换为对应实现提供的GC统计接口即可。

内容的提问来源于stack exchange,提问作者Dr Rama Lakshmanan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 13:18:03