Reputation: 561
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
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
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