On Tue, Jun 29, 2021 at 12:04 PM Jonathan Simpson <[email protected]> wrote: > > On Monday, June 28, 2021 at 10:25:36 PM UTC-4 Sam Tobin-Hochstadt wrote: >> >> On Mon, Jun 28, 2021 at 9:46 PM Jonathan Simpson wrote: >> > >> > On Sunday, June 27, 2021 at 10:29:55 AM UTC-4 Robby Findler wrote: >> >> >> >> Replacing ` (~r x #:precision 1)` with `(number->string x)` and ditto for >> >> `y` eliminates the overhead of contracts and brings about another 4x >> >> speedup on my machine. >> > >> > >> > This is because the compiler is able to remove the contract checks, not >> > because number->string doesn't have a contract, correct? If it is the >> > compiler, is there any rule of thumb to determine when the compiler will >> > likely remove the contract checks? Using typed 'for' iterators seems to be >> > one case that the compiler optimizes, but can we rely on others? >> >> There are two possible meanings for "contract checks" here. One is >> "does it check that it gets the right kind of arguments, and raise an >> error if not". In that sense, every function that is not "unsafe" has >> contracts, certainly including `number->string`. The other meaning is >> "uses the `racket/contract` library". The `~r` function has a contract >> in that sense, while `number->string` does not, and that's a >> significant source of overhead. On my laptop, just removing the >> contract on `~r` in the source of the `racket/format` library speeds >> up Bogdan's revised program from 600ms to 200ms. >> >> Most of the time, the compiler does not remove either kind of contract >> check. Sometimes the first kind of contract check can be removed in >> the simplest of cases; the second kind is basically never removed by >> the compiler. There are other cases where macros can generate code >> that omits contract checks, as with the `for` forms when used with >> sequence generators like `in-list`, but that is again for simple >> checks. >> >> Sam > > > Thanks for the reply. I was under the impression that all of the racket > provided functions had full racket/contract contracts implemented at the > module boundary, which is what I thought was generating errors of the form: > --- > (number->string "aa") > ; number->string: contract violation > ; expected: number? > ; given: "aa" > ---
That error message is generated here: https://github.com/racket/racket/blob/master/racket/src/cs/rumble/number.ss#L364 It uses the term "contract", and the exception is an instance of `exn:fail:contract`, but it is not generated by the `racket/contract` library. > I take it that the contract error above was generated by a lower-level > contract then. I've only glanced at contracts, so I assume this is documented > somewhere. Is this section of the Reference referring to the simple contracts > that you mention? From https://docs.racket-lang.org/reference/contracts.html: > --- > Contracts come in two forms: those constructed by the various operations > listed in this section of the manual, and various ordinary Racket values that > double as contracts, including... > --- That whole section of the reference is about the `racket/contract` library, and thus the second kind of contracts that I mentioned. Sam -- 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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/CAK%3DHD%2BYVJbsqvBzT-52meaoj8vV9XkdXXPFC%3DgL1JTCVxNTizA%40mail.gmail.com.

