[plt-scheme] iterate over characters in string
[If you get two copies Noel, it is because I forgot to change the to-field]
Welsh wrote:
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
>> At Tue, 13 Aug 2002 14:23:03 GMT, MJ Ray wrote:
>>> Chris Uzdavinis <chris at atdesk.com> wrote:
>>>> * is there any kind of for-each function that
>> works on a string at
>>>> the byte level?
> There is probably something in srfi 13 or 14. I can
> never remember which number means which srfi.
It is srfi-13. It provides string-fold and string-for-each.
I have collected a few variations. The test string is
of length 1000000. The srfi-13 versions works at the
string at the byte level.
The fastest of the srfi-13 versions is:
(define (calc-checksum-jas2 line)
(define kons (lambda (c sum) (+ sum (char->integer c))))
(modulo (string-fold kons 0 line) 256))
The fastest of them all is
(define (calc-checksum-cu line)
(modulo (apply + (map char->integer (string->list line))) 256))
Note that the set! is the slowest of them all. Mutation is slow.
I wrapped them in a modulo, so the optimizer got a fair chance.
Furthermore I collect garbage before each test in order to
get similar timings. The result was:
orig
cpu time: 3024 real time: 3024 gc time: 0
mjr
cpu time: 2123 real time: 2123 gc time: 0
cu
cpu time: 1422 real time: 1422 gc time: 0
jas
cpu time: 3485 real time: 3485 gc time: 0
jas2
cpu time: 2924 real time: 2924 gc time: 0
jas3
cpu time: 4928 real time: 4928 gc time: 0
jas4
cpu time: 4677 real time: 4677 gc time: 0
O! I almost forgot. srfi-13 can be downloaded at
http://sourceforge.net/project/showfiles.php?group_id=19879&release_id=96118
and the documentation can be browsed at
http://srfi.schemers.org/srfi-13/srfi-13.html
Jens Axel Søgaard
(module checksum mzscheme
(provide test-all)
(require (lib "string.ss" "srfi" "13"))
(define (calc-checksum line)
(let loop ([checksum 0]
[chars (string->list line)])
(cond [(null? chars) (modulo checksum 256)]
[else (loop (+ checksum
(char->integer (car chars)))
(cdr chars))])))
(define (calc-checksum-mjr line)
(let ((ck 0))
(map (lambda (c) (set! ck (+ ck (char->integer c))))
(string->list line))
(modulo ck 256)))
(define (calc-checksum-cu line)
(modulo (apply + (map char->integer (string->list line))) 256))
(define (calc-checksum-jas line)
(define kons (lambda (c sum) (modulo (+ sum (char->integer c)) 256)))
(string-fold kons 0 line))
(define (calc-checksum-jas2 line)
(define kons (lambda (c sum) (+ sum (char->integer c))))
(modulo (string-fold kons 0 line) 256))
(define (calc-checksum-jas3 line)
(define sum 0)
(define (update! c)
(set! sum (modulo (+ sum (char->integer c)) 256)))
(string-for-each update! line)
sum)
(define (calc-checksum-jas4 line)
(define sum 0)
(define (update! c)
(set! sum (+ sum (char->integer c))))
(string-for-each update! line)
(modulo sum 256))
(define (test sym cs)
(display sym)
(newline)
(collect-garbage)
(time (cs (make-string 1000000 #\a))))
(define (test-all)
(test 'orig calc-checksum)
(test 'mjr calc-checksum-mjr)
(test 'cu calc-checksum-cu)
(test 'jas calc-checksum-jas)
(test 'jas2 calc-checksum-jas2)
(test 'jas3 calc-checksum-jas3)
(test 'jas4 calc-checksum-jas4)))
(require checksum)
(test-all)