-
Notifications
You must be signed in to change notification settings - Fork 231
Use new faster application snapshots for "pub global activate" #1683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
One thing that might make this tricky is that these snapshots are tied to a particular SDK version - I'm not sure if anything |
Additionally you have to train the snapshot on something but pub has no way of knowing a representative way to invoke the script in order to train it. I think you would have to add some sort of configuration or something to tell pub what to do? |
Regarding SDK versions, as far as I know the old/current snapshots is also tied to a specific version of Dart and pub already detects that and creates a new snapshot when that happens, so that should not be different. It also shows when a new version is available so there is some checks being done already. Regarding training, I have not been doing any training at all and there is still a big speedup. I think you could maybe increase the speedup even more with training but even without training it's a lot faster it seems to me. Correct me if I'm wrong, but the training is not required, it's just there to make things even faster? |
I am curious how you are building the snapshot? Afaik if you are adding Also, I don't know to much about how it actually works but it seems like running a script arbitrarily with zero args could be a potential security risk, or just have adverse side effects. |
@jakemac53 yes I run the script without any arguments, and it prints out the help section when I do so. The app uses the args package and is very similar to pub in structure. It's faster also with arguments, at least showing the help info for various commands. From the snapshot link above:
Is it not so that most or all classes gets parsed in many cases with a CLI app? For example:
|
If it is not possible to create the snapshot in a secure fashion then a flag could maybe do for all packages that don't do something bad when executed (I think that is most of them). It's worth noting that running any untrusted code from pub locally is a potential security risk and I think most CLI applications don't do anything without arguments. Another option could maybe be if it could be specified in some config file what snapshot type that should be generated. |
We could potentially allow users to declare snapshot arguments in the executables:
dartfmt:
bin: format
snapshot: --app-snapshot We'd probably want to wait until after #69 to do this, though, so people don't start relying on it as a hacky way of faking that functionality. |
That would work for me. =) |
Instead I think what we should do is stop eagerly creating snapshots and instead wait for the first This is becoming more pressing since we currently can't run with snapshots at all for Dart 2 mode and that makes things very slow. |
I'd really like to avoid the first run of an executable being super slow—that seems like a really bad user experience. I'd rather continue to generate script snapshots ahead-of-time, and then generate app-jit snapshots from those on the first run. This will still add some first-run overhead, but it'll be a lot faster than running app-jit compilation from source. Also, I think we need to use script snapshots for Dart 2 for now—it looks like as of 2.0.0-dev.55, application snapshots still aren't supported in Dart 2 mode (dart-lang/sdk#33176). |
Doing this ahead of time just moves the slowness to pub get/upgrade though right? I find it a lot more annoying when those commands are slow because they are pre-compiling snapshots I will never use, and presumably that will get a lot slower now. |
When the slowness is in If packages are shipping unused executables, maybe that's a problem we should solve separately, either by encouraging authors to ship executables as separate packages or providing dependers a way to indicate that they don't care about a given package's executables. |
This doesn't mean it has to be eagerly done for all executables though. For instance
I don't personally think this is the right approach - you should be able to ship with your package diagnostic tools and other utilities which most people won't use, but that you can direct them to use to solve or diagnose specific problems, and it shouldn't cause pub get/upgrade to be slower for everybody. These types of tools often are going to use internal apis so you don't really want to ship them as separate packages either.
You could potentially resolve this to some degree by letting package authors specify that certain executables should be lazily compiled. I would still strongly prefer lazy to be the default though. I would not want to push this on users, because it doesn't scale well (you just end up with the same code copied across every pubspec, and if the executable is renamed they all have to change). |
Here's a +1 for lazy.
…On Mon, May 21, 2018 at 7:23 AM Jacob MacDonald ***@***.***> wrote:
I think we should optimize for having pub clearly take responsibility for
that time rather than our users.
This doesn't mean it has to be eagerly done for all executables though.
For instance pub run ... could log a message like creating snapshot for
<executable>... so that its clear where the time is going.
If packages are shipping unused executables, maybe that's a problem we
should solve separately, either by encouraging authors to ship executables
as separate packages
I don't personally think this is the right approach - you should be able
to ship with your package diagnostic tools and other utilities which most
people won't use, but that you can direct them to use to solve or diagnose
specific problems, and it shouldn't cause pub get/upgrade to be slower for
everybody.
These types of tools often are going to use internal apis so you don't
really want to ship them as separate packages either.
or providing dependers a way to indicate that they don't care about a
given package's executables.
You could potentially resolve this to some degree by letting package
*authors* specify that certain executables should be lazily compiled. I
would still strongly prefer lazy to be the default though.
I would not want to push this on users, because it doesn't scale well (you
just end up with the same code copied across every pubspec, and if the
executable is renamed they all have to change).
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#1683 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AABCirPFFa9vX1_bwcNioMPQJV02cYjgks5t0s3TgaJpZM4OyTfk>
.
|
Any messages we might produce would conflict with an executable's ability
to use stdout to emit data.
…On Mon, May 21, 2018, 3:23 PM Jacob MacDonald ***@***.***> wrote:
I think we should optimize for having pub clearly take responsibility for
that time rather than our users.
This doesn't mean it has to be eagerly done for all executables though.
For instance pub run ... could log a message like creating snapshot for
<executable>... so that its clear where the time is going.
If packages are shipping unused executables, maybe that's a problem we
should solve separately, either by encouraging authors to ship executables
as separate packages
I don't personally think this is the right approach - you should be able
to ship with your package diagnostic tools and other utilities which most
people won't use, but that you can direct them to use to solve or diagnose
specific problems, and it shouldn't cause pub get/upgrade to be slower for
everybody.
These types of tools often are going to use internal apis so you don't
really want to ship them as separate packages either.
or providing dependers a way to indicate that they don't care about a
given package's executables.
You could potentially resolve this to some degree by letting package
*authors* specify that certain executables should be lazily compiled. I
would still strongly prefer lazy to be the default though.
I would not want to push this on users, because it doesn't scale well (you
just end up with the same code copied across every pubspec, and if the
executable is renamed they all have to change).
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#1683 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAAAvOwct4ofo5KGYfPNzmcGbzj2I5HTks5t0s3RgaJpZM4OyTfk>
.
|
This could be resolved with a |
I would be fine either with or without an opt-in by package authors or end users to eagerly parse binaries on
I think that |
I think lazy by default makes sense to me. TBH the only place the majority of users will "feel" it is likely the first run of |
What if instead of a flag it only did it when stdout/stderr were connected to a terminal? I don't think that would break any use cases. |
I bet I could find one where it does 😜 I don't think that users are going to be confused enough to risk the cases where the run appears connected to a terminal but precise output is necessary. |
I agree that if we do this lazily we should never print any output. |
There's another issue here that we haven't considered yet. We run all applications in isolates in order to ensure that standard IO and signals and so on are all hooked up properly. But the isolate API doesn't have a way of compiling an application snapshot. |
Good point - we could create non-optimized snapshots lazily still. Another alternative could be using |
Following this thread in from the issue on using --preview-dart-2 with pub, so some of this info may be irrelevant. I'm happy to create a new issue if needed.
On the isolate topic, FWIW, we have a lot of CLI tools that spawn more isolates. When testing those tools via |
We are now using "kernel/dill binaries" (since quite a while) they offer fast recompilation. Not sure if that is the best for global binaries... |
For global binaries AOT probably would be better, but it would be breaking to switch because they don't support mirrors... |
But are application snapshots faster than the current dill binaries? |
The terminology is a bit weird/inconsistent here so I am actually not entirely sure what you are talking about when you say "application snapshot". Would the be a trained VM snapshot or an AOT binary (dart compile exe)? Both of those will start up faster, but I am not sure pub could reasonably create a trained VM snapshot without additional help from the package. The AOT binary will have much more predictable performance regardless (and start up very fast), but it isn't necessarily faster in general. Depends on the program and how long it runs etc... and also this has been a rapidly evolving space so the answer now is probably different than it was last I tried to compare. |
Yeah - I meant trained VM snapshot - what is mentioned in the subject of this issue. We have been discussing several times moving to a model where we |
Ah ok, fwiw I am surprised these are even still a thing, now that AOT is pretty mature, and solves the same problems without requiring a representative training command. I do not think application snapshots are a good target for pub compilation because of requiring a representative command for training in order to be better than just precompiled dills. |
Hi,
I recently learned about and have been testing Dart's application snapshots. In my tests it speeds up execution quite a lot* and I was thinking it would be nice if
pub global activate
either used app snapshots by default or at least if it was possible to add a flag to support faster CLI apps.What do you think?
* In the CLI app I tested the speed up was from ~200 ms to ~50 ms, it's a very noticeable speedup. Currently I use a custom bash install script for this but using pub would be much easier for distribution.
The text was updated successfully, but these errors were encountered: