-
Notifications
You must be signed in to change notification settings - Fork 194
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
Fix image loading for packaged apps #1427
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool stuff! I'm only a bit worried that it might end up causing us some troubles somewhere else but I don't hope so! Cool stuff, thank you @jasonrclark ! 🎉
Yeah, as I've pondered it further I wonder how this will fare with memory and performance on large images. I'm planning to do more testing on this than usual... Part of what I like about this approach is that it is always executed, which gets us tons more natural testing than something that only happens in packaged apps. That said, if we hit problems with it at all, we could do like the downloading does, and simply copy any image referenced from Anyway, will see what the testing looks like and report back! |
So, initial testing results (couldn't help myself 😀). Running with normal sized JPG images, I don't necessarily notice a huge difference, even when loading quite a few of them. But to stress test things, I grabbed a 60MB JPG of the Hubble Deep Field.
So that looks like a 50% slowdown on image loading... feels like that's significant warrant trying out the temp file approach instead. What do you think @PragTob. |
Hm. I'd like to see that benchmark to gauge it :D I.e. what are you measuring, the whole script? Just the image creation? :) If possible I'd like to have a benchmark-ips of the creation of the image... but that might be hard-ish to get :| Even then, 60MB is huge. If it really just occurs then it's fine imo as it's enough of an edge case for us to ignore atm (imo). We could also roll with this and create a separate ticket to investigate performance, we should probably also add a sample to make sure that it keeps working even when we improve performance :) |
Yeah, this was just a quick benchmark by doing |
Hm the problem might be graver then, if you really used |
EDIT: Revised results posted below after realizing my flagging was running the wrong thing 😨 |
756ff38
to
5f7fb06
Compare
As expected it was a bit of effort, but worth it, to get benchmarking closer around the image creation. This creates Rubocop is unhappy, but that's great since it will keep things red until we pick which one and resolve it on the branch. Full results are over in this gist but I'll pick out the salient details:
Interesting result here, the smallest file size was consistently faster with the byte reading approach this PR started with! But that clearly doesn't hold very long, as even up to about 200K for the file size the raw bytes is already much slower. While the scaling isn't totally obvious, for anything of even moderate size, copying to a tmp location holds much closer to just letting SWT work off the filename (which we can't do within packages). Upshot: I think we should take the tmpfile copying approach, but only do it when we detect that we're within a package and it's necessary. This keeps maximal performance with the normal execution, keeps as close as we can within packages, and the code is pretty straight-forward so I'm less worried about exercising it less often. That said, I need to extend the range of packaging samples that I use for releases this go around, since the existing single-file-no-images test I've been using isn't adequate anymore. What say you @PragTob? |
I'd be inclined to use tmp files all the way. Performance hit for very small files is sort of big but we could still do 900 of them in a second which is good enough. Afterwards the performance is almost on par and I think I'd rather make that tradeoff than implementing 2 code paths, I'd argue it's more pragmatic/easier to maintain. Should it turn out to be a big issue we could still optimize performance later on. Thanks for benchmarking ❤️ |
SWT doesn't understand the embedded file paths that warbler creates (uri:classloader), and so even when you give a properly calculated relative path to an image in your JAR, it'd fail noisily. To address this, we copy image files to a temporary location from Ruby-land (which knows how to interpret those file paths) and create our SWT images from those resulting, normal paths.
5f7fb06
to
0f95bfe
Compare
I buy it... pushed up a largely untested (but Rubocop clear!) version of copying to tmp location along with cleanup. Done for the night with almost no testing, so that'll be what I pick up next. Ready to run the samples + packaging gauntlet! |
Some test doesn't wanna play:
|
Had wondered if I should wrap up that temp clean up in some rescues... looks like that's a "yes!" |
If something fails during temp file removal... meh.
Updated to fix the tests which look like they'll be happy now. Also extended to spec out the behavior was seeing on Travis. Looking to get to the testing this weekend and will remove the WIP when that gets done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some good updates!
@@ -19,7 +19,7 @@ | |||
|
|||
subject do | |||
allow(dsl).to receive(:file_path) { image } | |||
Shoes::Swt::Image.new(dsl, swt_app) | |||
dsl.gui |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:)
If we do downloading temp files, they get cleaned up before we're completely done, so we use the list twice.
Found two issues in testing. First, we weren't making a temp copy of the static 'downloading' image that we show for URLs, so that borked when packaged. Second, cleanup happens after the SWT image is made. But for a downloading image, we actually end up making two separate images--the downloading one and the other. Since we didn't clear the list after the downloading temp was deleted, we get a false warning on the second. Easy enough to address. Bit more testing and then I think I'll get this merged tonight. I've noticed some other things around images + packaging that we can improve, but they're grounds for another PR. |
SWT doesn't understand the embedded file paths that warbler creates
(uri:classloader), and so even when you give a properly calculated
relative path to an image in your JAR, it'd fail noisily.
To address this, we
load the image from the filecopy those files inRuby-land (which knows how to interpret those file paths) and always
just create images directly
with the byte arrays.from those temp files.What's remaining? TESTING! Did a bit but not satisfied yet, and don't
have the gumption to finish tonight so thought I'd get the PR rolling
anyway.
Fixes #676. Potentially also does the same for #1422 as long as images
were the only concern there.
shoes
executableimage
calls in them)!