I ran this on DrRacket and Racket REPL, the performance difference is huge. In DrRacket it’s about 16x slower than in Racket REPL. In DrRacket: > (time (for ([i (in-range 10000000)])
(void)))
cpu time: 115 real time: 115 gc time: 0
In Racket REPL: > (time (for ([i (in-range 10000000)])
(void)))
cpu time: 7 real time: 7 gc time: 0
Does anyone know how to make it run as fast as REPL in DrRacket?
I don’t think you can make it run as fast, but you can speed it up by turning off debugging and profiling in the language details.
you have to click details in the language menu
@spdegabrielle Thanks, after turn off debugging and profiling, it becomes. cpu time: 20 real time: 20 gc time: 0
If I disable Preserve stacktrace, I got. cpu time: 7 real time: 7 gc time: 0
Which is pretty good.
However, conventional development environments usually separates debugging build/run from normal build/run. Don’t know if DrRacket can do the same?
@wanpeebaw Isn’t that what the button is doing?
An easy to find drop-down to switch between w/wo debugging, w/wo profiling would be a good thing. New-comers are always suprised that DrRacket instruments the code before running it.
Perhaps with a “triangle dropdown”.
(from Geogebra)
I think you can think of a pict like it’s a sort of image format, though it’s closer to something like SVG or Postscript than a bitmap. But picts are also immutable, so you can’t draw “into” one. pict
can’t implement dc<%>
because dc<%>
works by modifying the underlying canvas, which is incompatible with pict’s model.
With pict you can do something like (hc-append p (scale p 2))
and it all works out nicely—you get two of the same pict side by side, one of them at twice the size. But if pict
implemented dc<%>
, drawing “into” it would affect both picts (and any other picts derived from those ones), which is undesirable.
@soegaard2 This is how IntelliJ IDEA’s run/debug toolbar looks. And the hot-key are ^R for Run and ^D for Debug.
This is Xcode’s menu, which also separate Run from Test and Profile.
@wanpeebaw the issue is that Racket without any debugging or profiling is much harder to debug than Java without any debugging or profiling. Java exceptions still get stack traces when running normally. Racket exceptions don’t, and the handling of tail calls means getting something approximately like a useful stack trace is not possible without instrumenting the code in the way DrRacket does. That’s why it’s on by default instead of off by default.
Racket exceptions get stack traces even without any of the instrumentation, although it’s not as good with errortrace and with inlining disabled.
How not-as-good are they?
Without errortrace, you only get functions, not expressions (similar to what you’d see in Java). With inlining on, you can miss lots of frames that are relevant. Combined with tail calls, it can be a lot worse, but I basically never have them on unless I need specifically to help debugging something.
What’s the default when running racket
at the command line?
errortrace is not on, and inlining is enabled
ah, is that what people using racket-mode also see?
I believe so, but @greg knows for sure
@greg has joined the channel
I usually default it to medium
. If an error message isn’t specific enough, I re-run with the C-u
prefix to get high
temporarily.
high
can be slow. So I like this combo of “medium by default, high if/as/when helpful”.
what is the default default?
@jack ^
Derp. @notjack ^
@samth The default default is medium
.
So just compile-context-preservation-enabled #t
.
btw if you do run with high
, i.e. errortrace instrumentation, if you use a time
expression the REPL prints a comment: ; Warning: time or time-apply used in errortrace annotated code.
; For meaningful timings, use command-line racket instead!
(in Racket Mode)
I added that mainly to help myself, after posting a couple performance “measurements” on Racket Users, then later feeling embarrassed. :smile:
“I am here to inform you about an important micro-benchmark I have observed!” …. “Oh. Derp.”
I have to say that the first impression of the performance greatly affect the adoption rate of the language. Especially when people in the industry try to evaluate whether to use this language in their products.
I think it is a good point - DrRacket by default has debugging on even if you your press run. This is confusing for people coming from other IDE’s where you explicitly choose to debug.
Hello. It is possible to create a structure without field like: (define-struct none [])
Are there examples that show the usefulness of such a structure ? Thank you !
Yes. That’s possible.
When you define a struct using struct
you can give a struct a “super” struct. (struct name-of-a-struct name-of-super-struct (field …))
The new struct name-of-a-struct now gets the same fields as name-of-super-struct did plus the new fields field …
It make it easy to make a “hierarchy” of structs.
I understand. Thank you !
Another use case may be to create canary values.
In metapict
I have this example: ;;; Labels
(struct label (string-or-pict pos plc) #:transparent)
;;; Label placements
(struct placement ())
(struct lft placement()) ; left
(struct rt placement()) ; right
(struct top placement()) ; top
(struct bot placement()) ; bottom
Now placement?
will work on lft, rt, etc structs.
Thank you !
@popa.bogdanp I have a guess, but not sure: What do you mean by “canary” values?
A singleton value that is easy to recognize, like:
(define-values (canary canary?)
(let ()
(struct canary ())
(values (canary) canary?)))
if my API exposes canary
to a user, then it can easily recognize that specific value and the user can’t create any new ones like it.
I feel like I’ve used this in Racket libraries a few times, but I can’t think of any examples off the top of my head.
@wanpeebaw I agree that can be important (although there are many counter-examples). Just to be clear, I was talking about myself in the past being excited I’d discovered some performance issue with Racket… but I’d only discovered something about errrotrace
annotated code. I was poking fun at myself.
There are other ways you could achieve the same sort of thing, but I like (ab)using structs for this because they also print nicely
Maybe eof
and eof-object?
?
Ah, yep, perfect example
Got it. Thanks.
I think I would call those values singletons or perhaps unique values.
Well, they are singletons, but the ability to recognize them is also important
Which isn’t necessarily required for a singleton
True.
In the good old days (in the r5rs-era) I used (list 'canary)
to produce such values. These days I use structs too.
That reminds me of some history of “undefined” in Racket… but that history is maybe not #beginners material
That’s a true canary!
@arunsk.tec has joined the channel
Rebellion has a singleton type that automates a bit of the creation of such a type: https://docs.racket-lang.org/rebellion/Singleton_Types.html
It also has enum types for creating multiple singletons with a shared predicate https://docs.racket-lang.org/rebellion/Enum_Types.html
singleton types: (define-singleton-type null)
> null
#<null>
> (null? null)
#t
enum types: (define-enum-type direction (north south east west))
> north
#<direction:north>
> (direction? south)
#t
@wanpeebaw I agree, but also see Python
@chas has joined the channel
@johnsmithaaa100 has joined the channel
@notjack Well, better to have both, ease of use and yet very efficient.
When I started to learn Racket, due to the slow startup time and huge memory consumption of DrRacket, the overall impression given to me was that it’s very inefficient.
After done some micro-benchmark, it did show that it did not perform well (Now I know it’s due to the debugging stuff), and It did make me hesitate. But I still want to try it, because I am very interested in its expressiveness. And I’m happy to find out it’s actually quite fast.
My point is, the impression of this language is not very efficient, which is bad, and will scare some people out. It would be better if not the case. :slightly_smiling_face: