Re: [racket-users] Narrow radix of string->number.
I'm skeptical of an unbounded cache. If we go by the sample from DrRacket's start up, then we don't really need a cache to do better than the built-in number->string. Below is some code that takes the version I had earlier with what I understood to be Gustavo's suggestions and then just does better on the fixnums between 0 and 9. I then changed the random inputs to sample from the distribution that DrRacket demonstrated and you won't be surprised to learn that this does better than having a cache. Below is the code. I also tried to collect the arguments to number->string during rebuilding all of the .zo files. Of the first 2.3 million calls about 99.5% of them were exact integers between 0 and 9 so probably this is the only optimization we need to do. (My sampling method turned out to be noisy, tho, but I don't think it affects the results.) ... unless someone comes up with some other benchmark or app we care about? Robby #lang racket (require (for-syntax syntax/parse)) (define-syntax (mk-sample stx) (syntax-parse stx [(_ (value:exact-nonnegative-integer occurrences:exact-nonnegative-integer) ...) (define-values (cond-clauses count) (for/fold ([other-cases '()] [so-far 0]) ([value (in-list (syntax->list #'(value ...)))] [occurrences (in-list (syntax->list #'(occurrences ...)))]) (define next-count (+ so-far (syntax-e occurrences))) (values (cons #`[(< x #,next-count) #,value] other-cases) next-count))) #`(λ () (define x (random #,count)) (cond #,@(reverse cond-clauses)))])) (define sample/drr (mk-sample (0 2399) (1 8116) (2 4278) (3 2196) (4 1346) (5 901) (6 364) (7 230) (8 106) (9 96) (10 42) (11 5) (12 3) (72 1) (100 34) (241 1))) (define number->string** (let ([digits (list->vector (string->list "0123456789"))] [cache (make-hasheqv)]) (λ (N) (hash-ref! cache N (λ () (list->string (let loop ([N N][acc empty]) (define q (quotient N 10)) (define next-acc (cons (vector-ref digits (remainder N 10)) acc)) (if (zero? q) next-acc (loop q next-acc) (define (number->string* N) (cond [(and (exact-nonnegative-integer? N) (< N 10)) (string (integer->char (+ (char->integer #\0) N)))] [else (let* ([short-size 10] [str (make-string short-size)]) (let loop ([N N] [digits null] [i short-size]) (cond [(zero? N) (if (<= i 0) (if (null? digits) str (string-append (apply string digits) str)) (substring str i short-size))] [else (define q (quotient N 10)) (define r (remainder N 10)) (define d (integer->char (+ r (char->integer #\0 (cond [(<= i 0) (loop q (cons d digits) i)] [else (string-set! str (- i 1) d) (loop q '() (- i 1))])])))])) (define-syntax-rule (test-it id ...) (begin (module+ test (require rackunit) (check-equal? (id 1234567890987654321) (number->string 1234567890987654321)) (for ([x (in-range 1)]) (check-equal? (id x ) (number->string x ...)) (test-it number->string**) (test-it number->string*) (define iterations 1) (define-syntax-rule (time-it id ...) (begin (define numbers (for/list ([i (in-range 1000)]) (sample/drr))) (begin (collect-garbage) (time (for* ([x (in-range iterations)] [n (in-list numbers)]) (id n)) (printf "~a " 'id))) ...)) (time-it number->string number->string* number->string**) -- 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] Errors in (Dr)Racket
I mostly agree with Matthias, but wanted to add two things: 1) I've certainly experienced, many times, (both as the producer and consumer (and sometimes simultaneously)) contracts that were added because of runtime errors. But I do agree it is not as common as we had hoped it would be. And Stephen's comments suggest that there is a cultural issue here. So in that spirit, I want to say: please report (as bugs!) code that raises errors down in its bowels instead of at some more natural boundary in the code. 2) there is a technical difference between where the error is discovered and where the contract goes and the error messages generally have both of these components in them. It may be that the error message text isn't clear and these two separate things are getting conflated. (Overall, it is okay if the error is actually discovered in the bowels and this information shows up in the stack trace attached to the error message; the thing Matthias and I are thinking about is whether or not there is a contract that lives at some more reasonable boundary between the library you're using and the code you wrote that uses it.) Regardless, do post these errors. Feel free to ask if they seem to be missing checks or if something else is going on and lets try to build a better culture about getting good error messages! Happy New Year. :) Robby On Sun, Jan 1, 2017 at 12:51 PM, Matthias Felleisenwrote: > >> On Jan 1, 2017, at 1:17 PM, Stephen De Gabrielle >> wrote: >> >> Hi All, >> >> I occasionally write code with errors* that cause the DrRacket error message >> to link to an internal Racket file, rather than my own incorrect code. >> >> The last time I did this it was doing web server code, but I've also managed >> it with GUI code.(and playing with DrRacket Plugins) >> >> I've not filed a report (or attempted a patch) on this before, mostly out of >> embarrassment, but also because because I feel out of my depth in the racket >> internals and the error was in my own code. >> >> Should I report these when I find them? Should I attempt to work out the >> cause and attempt a patch? > > > A long time ago, Robby and I conjectured that if people reported those kinds > of errors, the creators of libraries would eventually protect their APIs with > contracts and the software would become more robust. This ‘gradual hardening’ > with contracts did not happen over time. Sure, some people added contracts to > libraries, others wrote them in Typed Racket. But all in all, we added > contracts because we wanted to not because of ‘client pressure.’ > > Your email is validation that something was wrong with our conjecture, but I > can’t figure out what exactly is wrong. The word ‘fear’ and ‘embarrassment’ > are suggestive. Perhaps developers are intimidated by the creators APIs and > Libraries, because these people must be so much better and can’t possibly > make mistakes. > > Well we all make mistakes and if others report them, we get better at > overcoming these mistakes (starting with the elimination of bugs). > > Happy New Year — Matthias > > -- > 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] Errors in (Dr)Racket
> On Jan 1, 2017, at 1:17 PM, Stephen De Gabrielle> wrote: > > Hi All, > > I occasionally write code with errors* that cause the DrRacket error message > to link to an internal Racket file, rather than my own incorrect code. > > The last time I did this it was doing web server code, but I've also managed > it with GUI code.(and playing with DrRacket Plugins) > > I've not filed a report (or attempted a patch) on this before, mostly out of > embarrassment, but also because because I feel out of my depth in the racket > internals and the error was in my own code. > > Should I report these when I find them? Should I attempt to work out the > cause and attempt a patch? A long time ago, Robby and I conjectured that if people reported those kinds of errors, the creators of libraries would eventually protect their APIs with contracts and the software would become more robust. This ‘gradual hardening’ with contracts did not happen over time. Sure, some people added contracts to libraries, others wrote them in Typed Racket. But all in all, we added contracts because we wanted to not because of ‘client pressure.’ Your email is validation that something was wrong with our conjecture, but I can’t figure out what exactly is wrong. The word ‘fear’ and ‘embarrassment’ are suggestive. Perhaps developers are intimidated by the creators APIs and Libraries, because these people must be so much better and can’t possibly make mistakes. Well we all make mistakes and if others report them, we get better at overcoming these mistakes (starting with the elimination of bugs). Happy New Year — Matthias -- 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] Errors in (Dr)Racket
Hi All, I occasionally write code with errors* that cause the DrRacket error message to link to an internal Racket file, rather than my own incorrect code. The last time I did this it was doing web server code, but I've also managed it with GUI code.(and playing with DrRacket Plugins) I've not filed a report (or attempted a patch) on this before, mostly out of embarrassment, but also because because I feel out of my depth in the racket internals and the error was in my own code. Should I report these when I find them? Should I attempt to work out the cause and attempt a patch? Kind Regards (and Happy New Year) Stephen * who am I kidding? my code is *mostly* errors :) -- Kind regards, Stephen -- Bigger than Scheme, cooler than Clojure & more fun than CL.(n=1) -- -- 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] Narrow radix of string->number.
> On Dec 31, 2016, at 12:05 PM, Robby Findler> wrote: > > But this introduces an additional cost that's a little bit more > troublesome to measure. Specifically, each namespace that instantiates > `racket/base` will now take a tiny bit more space and take a tiny bit > longer to initialize. > As one data point, here's a histogram of the 20k or so calls to > number->string that happen during the start up of DrRacket (first > entry in each list is the argument passed to number->string and the > second is the number of times that call happened) Hmm, well if the distribution of inputs is that imbalanced, perhaps this is the better cheat: ; 100,000 conversions of 100 random integers < 123 cpu time: 779 real time: 791 gc time: 16; number->string cpu time: 769 real time: 771 gc time: 13; number->string** ; 100,000 conversions of 100 random integers < 123456 cpu time: 1365 real time: 1384 gc time: 22 ; number->string cpu time: 941 real time: 955 gc time: 13; number->string** ; 100,000 conversions of 100 random integers < 123456789 cpu time: 1891 real time: 1904 gc time: 26 ; number->string cpu time: 963 real time: 979 gc time: 17; number->string** ; #lang racket (define number->string** (let ([digits (list->vector (string->list "0123456789"))] [cache (make-hasheqv)]) (λ (N) (hash-ref! cache N (λ () (list->string (let loop ([N N][acc empty]) (define q (quotient N 10)) (define next-acc (cons (vector-ref digits (remainder N 10)) acc)) (if (zero? q) next-acc (loop q next-acc) (define-syntax-rule (test-it id ...) (begin (module+ test (require rackunit) (check-equal? (id 1234567890987654321) (number->string 1234567890987654321)) (for ([x (in-range 1)]) (check-equal? (id x ) (number->string x ...)) (test-it number->string**) (define iterations 10) (define-syntax-rule (time-it number-to-convert id ...) (begin (define numbers (for/list ([i (in-range 100)]) (random number-to-convert))) (begin (collect-garbage) (time (for* ([x (in-range iterations)] [n (in-list numbers)]) (id n ...)) (time-it 123 number->string number->string**) (time-it 123456 number->string number->string**) (time-it 123456789 number->string number->string**) -- 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.