cs: faster list?
This commit is contained in:
parent
11e7598021
commit
723232081c
|
@ -5,34 +5,51 @@
|
||||||
;; where a second request will cache at the N/4-tail pair, etc.
|
;; where a second request will cache at the N/4-tail pair, etc.
|
||||||
;; Detect cycles using the same `slow` tortoise that is used for
|
;; Detect cycles using the same `slow` tortoise that is used for
|
||||||
;; caching.
|
;; caching.
|
||||||
|
;;
|
||||||
|
;; To reduce the overhead of checking the hash table, only
|
||||||
|
;; start using it after the first `CHECK-AFTER-LEN` pairs.
|
||||||
|
;; Then, check only every `CHECK-EVERY` pairs --- and record
|
||||||
|
;; a sequence of `CHECK-EVERY` results so one will hit when
|
||||||
|
;; checking every `CHECK-EVERY` pairs.
|
||||||
|
|
||||||
(define-thread-local lists (make-weak-eq-hashtable))
|
(define-thread-local lists (make-weak-eq-hashtable))
|
||||||
|
|
||||||
|
(define CHECK-AFTER-LEN 32)
|
||||||
|
(define CHECK-EVERY 4)
|
||||||
|
|
||||||
(define (list? v)
|
(define (list? v)
|
||||||
(let loop ([v v] [depth 0])
|
(let loop ([v v] [count 0])
|
||||||
(cond
|
(cond
|
||||||
[(null? v) #t]
|
[(null? v) #t]
|
||||||
[(not (pair? v)) #f]
|
[(not (pair? v)) #f]
|
||||||
[(pair? v)
|
|
||||||
(cond
|
|
||||||
[(fx<= depth 32)
|
|
||||||
(loop (cdr v) (fx+ depth 1))]
|
|
||||||
[else
|
[else
|
||||||
(let loop ([fast (cdr v)] [slow v] [slow-step? #f])
|
(cond
|
||||||
|
[(fx<= count CHECK-AFTER-LEN)
|
||||||
|
(loop (cdr v) (fx+ count 1))]
|
||||||
|
[else
|
||||||
|
(let ([lists lists])
|
||||||
|
(let loop ([fast (cdr v)] [slow v] [slow-step? #f] [countdown 0])
|
||||||
(let ([return (lambda (result)
|
(let ([return (lambda (result)
|
||||||
(hashtable-set! lists slow result)
|
(eq-hashtable-set! lists slow result)
|
||||||
|
(let loop ([slow slow] [count (fx- CHECK-EVERY 1)])
|
||||||
|
(unless (or (eq? slow fast)
|
||||||
|
(fx= count 0))
|
||||||
|
(eq-hashtable-set! lists slow result)
|
||||||
|
(loop (cdr slow) (fx- count 1))))
|
||||||
result)])
|
result)])
|
||||||
(cond
|
(cond
|
||||||
[(null? fast) (return #t)]
|
[(null? fast) (return #t)]
|
||||||
[(not (pair? fast)) (return #f)]
|
[(not (pair? fast)) (return #f)]
|
||||||
[(eq? fast slow) (return #f)] ; cycle
|
[(eq? fast slow) (return #f)] ; cycle
|
||||||
[else
|
[(fx= 0 countdown)
|
||||||
(let ([is-list? (hashtable-ref lists fast none)])
|
(let ([is-list? (eq-hashtable-ref lists fast none)])
|
||||||
(cond
|
(cond
|
||||||
[(eq? is-list? none)
|
[(eq? is-list? none)
|
||||||
(loop (cdr fast) (if slow-step? (cdr slow) slow) (not slow-step?))]
|
(loop (cdr fast) (if slow-step? (cdr slow) slow) (not slow-step?) CHECK-EVERY)]
|
||||||
[else
|
[else
|
||||||
(return is-list?)]))])))])])))
|
(return is-list?)]))]
|
||||||
|
[else
|
||||||
|
(loop (cdr fast) (if slow-step? (cdr slow) slow) (not slow-step?) (fx- countdown 1))]))))])])))
|
||||||
|
|
||||||
(define (append-n l n l2)
|
(define (append-n l n l2)
|
||||||
(cond
|
(cond
|
||||||
|
|
Loading…
Reference in New Issue
Block a user