ajukraine
ajukraine

Reputation: 561

Common Lisp: The fastest way to read the stream

folks, what is the fastest approach for reading the stream in Common Lisp (SBCL) ?

For me, that is read-line. But suddenly I've stuck with the performance problem with this function - I should read 10kk characters (1000 lines with 10000 chars at each) in 1.5 sec, but read-line failed to achieve it. Is it possible with Common Lisp? Does it provide a C-style scanf() function for fast reading?

Thanks!

UPDATE. The code:

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

Upvotes: 1

Views: 1945

Answers (2)

Daniel Dickison
Daniel Dickison

Reputation: 21882

Without profiling it's impossible to tell exactly where your bottlenecks are, but my guess is that split and solve are slowing you down. Specifically, when you call subseq on the string to split it, you end up allocating two new strings. Since parse-integer can take the start and end indices into the string, there's no need to do the split:

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

Upvotes: 4

Xach
Xach

Reputation: 11854

Performance for text-oriented I/O can vary quite a lot between implementations, and the strategies that help improve performance on one implementation might not apply to another. What implementation are you using?

Are the lines guaranteed to be the same length?

For what it's worth, I tried your exercise (1,000 lines of 10,000 characters each) and it took about 0.25 seconds to read in SBCL.

Upvotes: 4

Related Questions