Thanks Sam, Robby. Your explanations make perfect sense. I was conflating contract exceptions with the contract library. I had just assumed they were one and the same. Avoiding the contract library for performance reasons in some cases also seems quite reasonable to me.
Thanks again! -- Jonathan On Tuesday, June 29, 2021 at 12:45:15 PM UTC-4 Robby Findler wrote: > A little more information about these things. > > I'd say that there are two obstacles to having the racket/contract library > actually be the source of the contract checks in all functions exported by > the racket language/library: > > 1) dependency layering. The racket/contract library is really a library. > So if that library needs something to actually implement the contract > system (eg string manipulation libraries, which are handy for constructing > error messages), then it can't have a contract that is implemented by the > library > > 2) performance. The contract system has gobs of special cases to get quite > close in various situations but it still doesn't quite ever achieve the > performance of just writing a simple check at the start of the function > (unfortunately). It can be difficult to predict which cases those are (and > there are plenty of situations when the raw overhead of the contract > checking isn't what matters for the performance) but this is an area I'd > like to improve somehow. > > One consequence is that some care has been taken, both in the contract > system and in functions like number->string, to make the error messages > look uniform. A giveaway, however, is the "blaming" line, which the > racket/contract contract checking always has and the simple number->string > function checks do not. Including that line forces us to give up on the > performance benefits of just doing the simple check (since that line > requires a precise accounting of who called whom and we have only an > approximate accounting of that from a stacktrace unless we add what has > been deemed (quite reasonably, IMO) unacceptable overhead). > > hth,Robby > > > On Tue, Jun 29, 2021 at 11:11 AM Sam Tobin-Hochstadt <[email protected]> > wrote: > >> 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 >> . >> > -- 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/a47d2817-a9a9-45a6-bdd7-bbbefc78ba9bn%40googlegroups.com.

