Common Lisp:读取流的最快方法

时间:2011-05-27 12:10:25

标签: common-lisp sbcl

伙计们,在Common Lisp(SBCL)中读取流的最快方法是什么?

对我来说,这是读取线。但是我突然停止了这个函数的性能问题 - 我应该在1.5秒内读取10kk字符(1000行,每行10000个字符),但读取行无法实现。 Common Lisp有可能吗?它是否提供C风格的 scanf()功能以便快速阅读?

谢谢!

更新即可。代码:

(defun split (string)
  (let ((space-position (position #\Space string)))
    (list 
     (subseq string 0 space-position) 
     (subseq string (+ space-position 1)))))

(defun solve (line)
  (let ((nums (split line))
    (first)
    (second))
    (setq first (parse-integer (car nums)))
    (setq second (parse-integer (cadr nums)))

    (* first second)))

(defun spoj()
  (let ((N (read))
        (line))
    (dotimes (i N)
      (setq line (read-line))
      (format t "~d~%" (solve line))))))

(spoj)

2 个答案:

答案 0 :(得分:4)

面向文本的I / O的性能在实现之间可能会有很大差异,有助于提高一个实现的性能的策略可能不适用于另一个实现。您使用的是什么实现?

线条保证长度相同吗?

为了它的价值,我尝试了你的练习(1000行,每行10000个字符),在SBCL中读了大约0.25秒。

答案 1 :(得分:3)

如果没有分析,就无法准确判断出瓶颈在哪里,但我的猜测是splitsolve正在减慢你的速度。具体来说,当您在字符串上调用subseq来拆分它时,最终会分配两个新字符串。由于parse-integer可以将开始和结束索引作为字符串,因此不需要进行拆分:

(let* ((space-position (position #\Space string))
       (first (parse-integer string :end space-position))
       (second (parse-integer string :start (1+ space-position)))
  (* first second))