Эффективная сумма списка случайных чисел в Racket - PullRequest
3 голосов
/ 30 ноября 2011

Каков был бы наиболее эффективный способ сначала сгенерировать, а затем суммировать список случайных целых чисел в Racket?

Я пытаюсь реализовать эквивалент кода в https://scottlocklin.wordpress.com/2011/11/30/only-fast-languages-are-interesting, но я могу только придумывать медленные имплементации.

Моя первая наивная попытка (не случайные целые числа, но в любом случае):

(define (sum-list l)
  (if (null? l)
      0
      (+ (first l) (sum-list (rest l)))))

(define avector 
    (build-vector 3000000 add1))

(time (sum-list avector))

Обратите внимание, что эффективной частью кода должна быть только действительная сумма списка, а не генерация.

Большое спасибо.

1 Ответ

6 голосов
/ 30 ноября 2011

Вот простая версия, использующая `vector's:

#lang racket    

(define N 3000000)
(define avector 
    (for/vector #:length N ([i (in-range N)]) (random)))

(define (sum-vec v)
  (for/fold ([i 0.0]) ([e (in-vector v)]) (+ e i)))

(time (sum-vec avector))

Это работает примерно на 250 мс на моей машине.

Если мы перейдем на использование flvector:

#lang racket

(require racket/flonum)

(define N 3000000)
(define avector 
    (for/flvector #:length N ([i (in-range N)]) (random)))

(define (sum-vec v)
  (for/fold ([i 0.0]) ([e (in-flvector v)]) (+ e i)))

(time (sum-vec avector))

Затем он запускается примерно через 60 мс.

Если мы изменим его на использование Typed Racket:

#lang typed/racket

(require racket/flonum)

(define N 3000000)
(define avector 
    (for/flvector #:length N ([i (in-range N)]) (random)))

(: sum-vec : FlVector -> Float)
(define (sum-vec v)
  (for/fold ([i 0.0]) ([e (in-flvector v)]) (+ e i)))

(time (sum-vec avector))

Теперь он работает примерно за 20 мс.

...