Re: [racket-users] Re: Fast way to map over a list many times, changing ONE element each time?

2015-06-22 Thread Jens Axel Søgaard
Hi Luke,

With 5000 numbers I got the numbers below with a slightly modified
benchmark.
If one method generates garbage and triggers a garbage collection while
running the following method, then the numbers will be unfair. To avoid
this I call collect-garbage before calling time.

map-once method number 1:
cpu time: 2832 real time: 3406 gc time: 1970
cpu time: 1895 real time: 1973 gc time: 1472
cpu time: 1941 real time: 2070 gc time: 1514


map-once method number 2:
cpu time: 2212 real time: 2288 gc time: 1687
cpu time: 2320 real time: 2395 gc time: 1766
cpu time: 2344 real time: 2451 gc time: 1815


map-once method number 3:
cpu time: 12547 real time: 13146 gc time: 11738
cpu time: 10687 real time: 10824 gc time: 9930
cpu time: 10615 real time: 10786 gc time: 9860


map-once method number 4:
cpu time: 1718 real time: 1795 gc time: 1379
cpu time: 1796 real time: 1827 gc time: 1403
cpu time: 1751 real time: 1816 gc time: 1380


map-once method number 5:
cpu time: 1311 real time: 1381 gc time: 1081
cpu time: 1346 real time: 1401 gc time: 1119
cpu time: 1375 real time: 1491 gc time: 1129


vector method:
cpu time: 1063 real time: 1154 gc time: 365
cpu time: 942 real time: 1024 gc time: 366
cpu time: 921 real time: 1002 gc time: 391


#lang racket
; testing for post on racket mailing list
; https://groups.google.com/forum/#!topic/racket-users/7lkOjjpVa6A

;; Luke
(define (map-once/1 f ls)
  (let M ([sooner null] [later ls])
(if (null? later) null
(cons (append sooner (list (f (car later))) (cdr later))
  (M (append sooner (list (car later))) (cdr later))


(define (list-set ls i new-val)
  (let-values ([(sooner later) (split-at ls i)])
(append sooner (list new-val) (cdr later

(define (map-once/2 f ls)
  (for/list ([i (in-naturals)]
 [elm (in-list ls)])
(list-set ls i (f elm

;; Jon
(define (map-once/3 fn xs)
  (for/list ([i (in-range (length xs))])
(for/list ([(x j) (in-indexed (in-list xs))])
  (cond [(= i j) (fn x)]
[else x]


(define (map-once/v fn xs)
  (build-vector (vector-length xs)
(λ (i)
  (define v (vector-copy xs))
  (vector-set! v i (fn (vector-ref v i)))
  v)))


;; Jens
(define (list-splits xs)
  (define (loop ys zs)  ; xs = (append (reverse ys) yz)
(match zs
  ['()  '()]
  [(cons z zs*) (cons (list ys zs)
  (loop (cons z ys) zs*))]))
  (loop '() xs))

(define (map-once/4 f xs)
  (for/list ([ys+zs (list-splits xs)])
(match ys+zs
  [(list ys '()) '()]
  [(list ys (cons z zs)) (append (reverse ys) (cons (f z) zs))])))


(require (only-in srfi/1 append-reverse))

(define (map-once/5 f xs)
  (for/list ([ys+zs (list-splits xs)])
(match ys+zs
  [(list ys '()) '()]
  [(list ys (cons z zs)) (append-reverse ys (cons (f z) zs))])))


;;; actual testing

(define num-test-cases 5000)
(define num-runs-per-f 3)

(define ls (for/list ([__ (in-range num-test-cases)]) (random)))

(define normal-map-onces
  (list map-once/1 map-once/2 map-once/3 map-once/4 map-once/5))

(for ([map-once (in-list normal-map-onces)]
  [i (in-naturals)])
  (printf "\n\nmap-once method number ~a:\n" (+ i 1))
  (for ([__ (in-range num-runs-per-f)])
(collect-garbage)
(collect-garbage)
(collect-garbage)
(time (void (map-once sqr ls)

(define v (for/vector ([__ (in-range num-test-cases)]) (random)))
(printf "\n\nvector method:\n")
(for ([__ (in-range num-runs-per-f)])
  (collect-garbage)
  (collect-garbage)
  (collect-garbage)
  (time (void (map-once/v sqr v


2015-06-19 23:08 GMT+02:00 Luke Miles :

> My 1000 numbers were so small that they weren't reliable.
>
> Change the `num-runs-per-f` and experiment yourself, if you'd like.
> The code is attached.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>



-- 
-- 
Jens Axel Søgaard

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Re: Fast way to map over a list many times, changing ONE element each time?

2015-06-21 Thread Jon Zeppieri
If you're willing to use vectors, then maybe you're also willing to
use a custom data structure? You could get much better performance
that way. Here's a half-baked example of what I mean. `map-once/h`,
below, returns a (normal list) of hole-lists. ("hole-list" is not a
good name. The offset doesn't really designate a hole in the list, but
the offset where the function should be applied.)
===

#lang racket/base

(require racket/match)

(struct hole-list (xs hole-offset fn))

(define (hole-list-empty? hxs)
  (match hxs
[(hole-list (? pair?) _ _) #f]
[_ #t]))

(define (hole-list-nonempty? hxs)
  (not (hole-list-empty? hxs)))

(define (hcar hxs)
  (match hxs
[(hole-list (cons x _) 0 fn) (fn x)]
[(hole-list (cons x _) _ _) x]))

(define (hcdr hxs)
  (match hxs
[(hole-list (cons _ xs) n fn) (hole-list xs (sub1 n) fn)]))

(define-match-expander hcons
  (syntax-rules ()
[(_ x xs) (and (? hole-list?)
   (? hole-list-nonempty?)
   (app hcar x)
   (app hcdr xs))]))

(define-match-expander hnull
  (syntax-rules ()
[(_) (and (? hole-list?)
  (? hole-list-empty?))]))

(define (hole-list->list hxs)
  (match hxs
[(hnull) '()]
[(hcons x xs) (cons x (hole-list->list xs))]))

(define (map-once/h fn xs)
  (for/list ([i (in-range (length xs))])
(hole-list xs i fn)))


On Fri, Jun 19, 2015 at 4:33 PM, Luke Miles  wrote:
> I timed all these with `sqr` on a list of 1 `(random)`.
>
> Luke's (my) first one:
> cpu time: 4706 real time: 4699 gc time: 3673
>
> Luke's second one:
> cpu time: 5401 real time: 5393 gc time: 4136
>
> Jon's first one:
> cpu time: 9734 real time: 9728 gc time: 8007
>
> Jon's second one (tested on a vector of course):
> cpu time: 1198 real time: 1195 gc time: 883
>
> Jens' first one:
> cpu time: 5622 real time: 5618 gc time: 4800
>
> Jens' second one:
> cpu time: 4393 real time: 4391 gc time: 3935
>
>
> I thought Jens' second one would be faster. The vector's results are 
> promising.
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Re: Fast way to map over a list many times, changing ONE element each time?

2015-06-19 Thread Luke Miles
My 1000 numbers were so small that they weren't reliable.

Change the `num-runs-per-f` and experiment yourself, if you'd like.
The code is attached.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


map-once.rkt
Description: Binary data


Re: [racket-users] Re: Fast way to map over a list many times, changing ONE element each time?

2015-06-19 Thread Jens Axel Søgaard
Hi Luke,

What are the result on lists of length 1000?

Also can you post the benchmarking code?

/Jens Axel



2015-06-19 22:33 GMT+02:00 Luke Miles :

> I timed all these with `sqr` on a list of 1 `(random)`.
>
> Luke's (my) first one:
> cpu time: 4706 real time: 4699 gc time: 3673
>
> Luke's second one:
> cpu time: 5401 real time: 5393 gc time: 4136
>
> Jon's first one:
> cpu time: 9734 real time: 9728 gc time: 8007
>
> Jon's second one (tested on a vector of course):
> cpu time: 1198 real time: 1195 gc time: 883
>
> Jens' first one:
> cpu time: 5622 real time: 5618 gc time: 4800
>
> Jens' second one:
> cpu time: 4393 real time: 4391 gc time: 3935
>
>
> I thought Jens' second one would be faster. The vector's results are
> promising.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>



-- 
-- 
Jens Axel Søgaard

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: Fast way to map over a list many times, changing ONE element each time?

2015-06-19 Thread Luke Miles
I timed all these with `sqr` on a list of 1 `(random)`.

Luke's (my) first one:
cpu time: 4706 real time: 4699 gc time: 3673

Luke's second one:
cpu time: 5401 real time: 5393 gc time: 4136

Jon's first one:
cpu time: 9734 real time: 9728 gc time: 8007

Jon's second one (tested on a vector of course):
cpu time: 1198 real time: 1195 gc time: 883

Jens' first one:
cpu time: 5622 real time: 5618 gc time: 4800

Jens' second one:
cpu time: 4393 real time: 4391 gc time: 3935


I thought Jens' second one would be faster. The vector's results are promising.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.