It's because on [-20, 0), sqrt produces imaginary numbers (try it in the repl), and plot filters them out, which apparently is pretty costly. This happens with other functions such as log, or functions that produce +nan.0 on a large portion of the x-axis. I'm not too sure why though.
plot uses Typed Racket and specifies a type for the argument to function that it takes Real to Real.
The type is translated to a contract when you use it in untyped Racket.
When plot passes inputs like -10 to sqrt that fails the contract, triggering a contract error, which involves some expensive computation to print out the error message (something about packages).
plot then catches the exception to just not show that point on the graph, and tries other values.
Since this happens for a lot of negative values, the expensive error-formatting computation happens a lot of times, resulting in the slow program you see.
The most obvious optimization is for the contract error printing to not be so slow (why does it need to call path->pkg+subpath every time?) but maybe there's a way for plot to be smarter too.
Maybe a good idea is for plot change its type to Number -> Number and then to silently discard non-reals but to stop catching the exceptions (or just catch the first one and make sure that one gets displayed somehow in a useful way). Not that I'm a super heavy user of plot but it seems like I'd want to know if I passed a function in that was doing (car #f) or something like that, instead of returning a number. (Of course, this ship may have sailed for backwards compatibility reasons so maybe this has to be optional behavior.)
Just thinking aloud:
How about delaying the evaluation of the exception message until it is actually used?
Maybe using a parameter defaulting to immediate evaluation, and otherwise the exn message is a thunk that needs to be applied to obtain the actual string.