1

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

对我来说,那是read-line。但是突然间我遇到了这个函数的性能问题——我应该在 1.5 秒内读取 10kk 个字符(1000 行,每个字符 10000 个字符),但 read-line 未能实现。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)
4

2 回答 2

4

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

线是否保证长度相同?

对于它的价值,我尝试了你的练习(1,000 行,每行 10,000 个字符),在 SBCL 中阅读大约需要 0.25 秒。

于 2011-05-27T13:53:08.160 回答
4

如果不进行分析,就不可能准确地知道你的瓶颈在哪里,但我的猜测是,这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))
于 2011-05-27T14:56:44.113 回答