Common Lisp:读取流的最快方式

问题描述:

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

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

谢谢!

UPDATE。代码:

(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) 
+0

你的瓶颈很可能是你与你_after_'琴弦做什么读line'他们。你可以发布你使用的代码吗? – 2011-05-27 14:04:04

+0

我正在使用SBCL。但看起来你是对的。在读取流之后,缓慢的事情发生在应用程序逻辑代码中。 其实,我使用** parse-integer **并通过长运算乘法。所以应用程序读取1000对整数(每个人10^4位)并打印每对乘法的结果。 – ajukraine 2011-05-27 14:14:42

表现为面向文本的I/O可以改变实现之间颇多,而且有助于提高一个实施绩效的策略可能不适用于其他。你使用什么实现?

线条是否保证长度相同?

为了什么是值得的,我尝试了你的练习(每行10,000个字符的1,000行),在SBCL中读取大约需要0.25秒。

+0

我正在使用SBCL。现在我认为这不是I/O问题。 – ajukraine 2011-05-27 14:15:58

没有分析它是不可能确切地告诉你的瓶颈在哪里,但我的猜测是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)) 
+0

感谢“良好的代码”:) 而我不知道配置文件Lisp ... – ajukraine 2011-05-27 15:11:44

+6

PARSE-INTEGER返回它消耗了多少字符串的第二个值,所以你也可以使用(mvb(第一个结尾)(parse-integer string:junk-allowed t)(* first(parse-integer string:start(1+ end):junk-allowed t)))或类似的。 – Xach 2011-05-27 15:32:41