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 <sa...@cs.indiana.edu> > wrote: > >> On Tue, Jun 29, 2021 at 12:04 PM Jonathan Simpson <jjsi...@gmail.com> >> 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 racket-users...@googlegroups.com. >> > 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 racket-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/a47d2817-a9a9-45a6-bdd7-bbbefc78ba9bn%40googlegroups.com.