Re: [racket-users] How to improve compile times?
Am 28.04.2017 um 08:07 schrieb Alex Harsanyi: > > In the end, the start up time does not bother me too much, as it is a GUI > application and I spend a lot of time using it after starting it up, so the 7 > second wait is acceptable. I have other, more interesting, application > features to work on anyway :-) > As one of the users of ActivityLog2 I do not mind the startup time either. Best wishes, Daniel -- 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. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] How to improve compile times?
On Friday, April 28, 2017 at 10:04:52 PM UTC+8, Matthew Flatt wrote: > I notice that your code calls `running-stickman-icon` on startup, which > takes about 2 seconds on my machine. Well, this is embarrassing for me. I remember adding that code in and having to decide on whether to wait 2 seconds for the "About" dialog to be ready or to compute the value at start up, delaying startup time. I made a mental note to create a PNG image and loading that, but forgot about doing it. Thanks for pointing it out. Alex. -- 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. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] How to improve compile times?
At Thu, 27 Apr 2017 23:07:01 -0700 (PDT), Alex Harsanyi wrote: > > * The size of the bytecode does matter (and switching to Chez scheme's > run-time could hopefully improve that) > > All the .zo files put together are about 4Mb. I'm not sure if this is big or > not? 4MB is not big. But your program pulls in `framework`, `plot`, and `math` (which is used by `plot`, anyway), which all have to be loaded and involve lots of bytecode. > What I'm wondering is if class definition actually runs some code when a > module is required, like the code below: > > (define my-class% >(class object% (init) (super-new) > (define/public (say-hello) (printf "hello~%" Yes, constructing the class does take some work, but it's unlikely to be a noticeable amount of work. I notice that your code calls `running-stickman-icon` on startup, which takes about 2 seconds on my machine. Meanwhile, just loading `plot`+`math`+`framework` takes about 2.5 seconds. Maybe there are some other slow-to-load libraries, and then maybe improving code-loading times in Racket will help for your application. -- 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. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] How to improve compile times?
At Thu, 27 Apr 2017 11:47:41 -0700 (PDT), Dupéron Georges wrote: > If I understand correctly, [...] Yes, that all looks right. > It would be nice to find a way to detect what code gets executed when > a module is required, at the various meta-levels. Maybe running raco > cover on an empty file containing only (require some-module) could > help? Yes, that sounds helpful. The module loader should log events about module loading an instantiation at various phases, and then a tool could put that information in a readable format. I'll add that to my "to do" list for the new expander. > I'm not sure how submodules fit in this picture (the main concerns being the > test submodule, and the doc submodule for literate programs). Submodules differ from top-level modules only in that compiling a module from source implies compiling its submodules, even if you do not run the submodules. In compiled form, however, submodule bytecode is loaded or not independent of other modules, so the existence of a `test` or `doc` submodule does not affect the time required to load the enclosing module by itself. -- 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. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] How to improve compile times?
> > * Alex Harsanyi's start-up time is due to run-time (phase 0) initialisation > > code in the required libraries, including things like (define v > > costly-expression), which look like they could be saved as constants, but > > actually involve running the expression. > > I actively try to avoid this case and I believe the program has little or no > such code anymore. However, even when I removed such cases, it did not seem > to make much difference. Racket code actually runs fast. Just a quick clarification: I meant that such initialisation code may be present in the libraries that you require, not in your own code (and so you do not have much control over this, unless you start modifying the libraries). > > * If Alex Harsanyi's code uses dynamic-require or eval, the phase 1 > > initialisation code of the required libraries is executed when eval or > > dynamic-require are first invoked. > > The code does not use any of those things. Also, apart from 3 macros dealing > with baking in some API KEYS at compile time, there are no uses of > `define-syntax` and friends. Again, there could be some use of eval within library code, or in code generated by library macros, even if there is no direct use of eval in your code. Nice application, by the way :) -- 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. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] How to improve compile times?
On Friday, April 28, 2017 at 2:47:41 AM UTC+8, Dupéron Georges wrote: > Thank you Matthew for the explanation. > > If I understand correctly, > > * Alex Harsanyi's start-up time is due to run-time (phase 0) initialisation > code in the required libraries, including things like (define v > costly-expression), which look like they could be saved as constants, but > actually involve running the expression. > I actively try to avoid this case and I believe the program has little or no such code anymore. However, even when I removed such cases, it did not seem to make much difference. Racket code actually runs fast. > * If Alex Harsanyi's code uses dynamic-require or eval, the phase 1 > initialisation code of the required libraries is executed when eval or > dynamic-require are first invoked. The code does not use any of those things. Also, apart from 3 macros dealing with baking in some API KEYS at compile time, there are no uses of `define-syntax` and friends. > * The size of the bytecode does matter (and switching to Chez scheme's > run-time could hopefully improve that) All the .zo files put together are about 4Mb. I'm not sure if this is big or not? What I'm wondering is if class definition actually runs some code when a module is required, like the code below: (define my-class% (class object% (init) (super-new) (define/public (say-hello) (printf "hello~%" In the end, the start up time does not bother me too much, as it is a GUI application and I spend a lot of time using it after starting it up, so the 7 second wait is acceptable. I have other, more interesting, application features to work on anyway :-) If anyone wants to look at the startup time, or help out with any other development, here is the application: https://github.com/alex-hhh/ActivityLog2 Best Regards, Alex. -- 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. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] How to improve compile times?
Thank you Matthew for the explanation. If I understand correctly, * Alex Harsanyi's start-up time is due to run-time (phase 0) initialisation code in the required libraries, including things like (define v costly-expression), which look like they could be saved as constants, but actually involve running the expression. * If Alex Harsanyi's code uses dynamic-require or eval, the phase 1 initialisation code of the required libraries is executed when eval or dynamic-require are first invoked. * The size of the bytecode does matter (and switching to Chez scheme's run-time could hopefully improve that) Concerning the definition of a macro: ;; a.rkt #lang racket (require "b.rkt") v ;; b.rkt #lang racket (require "c.rkt") (provide v) (define v (foo)) ;; c.rkt #lang racket (provide foo) (require racket/function) (define-syntax foo (curry (λ (v stx) (displayln v) #'1) (begin (displayln "XX") (string-append "c" "c" * The "cc" is printed when compiling b.rkt, but not when running a.rkt, nor when compiling a.rkt. * The curry and string-append are executed when compiling c.rkt, when c.rkt is instantiated because it is required by b.rkt, and another fresh instantiation of c.rkt is done when it is transitively required by a.rkt. This can be seen by running raco make c.rkt; raco make b.rkt; raco make a.rkt, and observing that XX is printed each time. * When executing racket a.rkt, no XX is printed unless eval is called at run-time at some point. My conclusions, in terms of performance hints are that: * It is safe to put code within the body of a transformer function (bound to a macro). * Code outside of transformer functions (to define compile-time constants, or the curry in the example above) has a cost when compiling all files which transitively require that module. It also has a one-time run-time cost if/when eval, dynamic-require or something similar is used. * The bytecode size has an impact too. * It is therefore better to avoid requiring too many modules if they are not needed. It would be nice to find a way to detect what code gets executed when a module is required, at the various meta-levels. Maybe running raco cover on an empty file containing only (require some-module) could help? I'm not sure how submodules fit in this picture (the main concerns being the test submodule, and the doc submodule for literate programs). -- 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. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] How to improve compile times?
At Wed, 26 Apr 2017 15:04:15 -0700 (PDT), Dupéron Georges wrote: > However, I'm not sure what operations can cause compile-time code to > be run in this situation. My (possibly incorrect) understanding is > that macros are executed only once (when expanding the code), but the > code to the right-hand-side of a (define-syntax foo > costly-operation), and the code within a (begin-for-syntax …) will > both be run each time the module is required. Each time a module is compiled, the compile-time code for any imported modules is run in fresh compile-time instantiations of those modules. ("Compile" = "expand" in this context.) So, given "a.rkt" as ;; a.rkt #lang racket (require "b.rkt") and "b.rkt" as ;; b.rkt #lang racket (begin-for-syntax (displayln "b")) if you use `racket a.rkt` leaving both modules as source, you'll see printed "b" twice: once when compiling "b.rkt", and once when compiling "a.rkt". If you use `raco make a.rkt`, you'll also see "b" printed twice, but then `racket a.rkt` will not print "b". If you have run `raco make a.rkt` already, then here's a potentially confusing result: % racket Welcome to Racket > (require "a.rkt") > 1 b 1 In this case, no "b" is printed to load and execute the runtime part of "a.rkt". Still, compile-time module instances have been created to handle further evaluation in the REPL. So, as soon as `eval` is called by the REPL for the expression `1`, the compile-time parts of "a.rkt" and "b.rkt" are run. That's why "b" prints, and why it prints so late. When you've compiled a program to bytecode and then run it, whether any compile-time code is run depends on whether you use `eval` or `dynamic-require` or similar. Another part of the run time is just reading in bytecode, though. The bytecode-loading part of Racket seems slower than it should be, and that was one of the things I had planned to rebuild --- but now I'm hoping that we'll get better load times by swapping Chez Scheme in place of the current runtime system. -- 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. For more options, visit https://groups.google.com/d/optout.