javacpp
javacpp copied to clipboard
Loading native libraries on Windows 10 takes a long time
I am using javacpp/ffmpeg on Windows 10 (2004) and found that loading the native libraries takes longer for Javacpp version 1.5.4 in comparison to 1.5.3. On 1.5.4 it takes roughly 7 seconds to load the libraries, which is in contrast to the 1.5 seconds version 1.5.3 takes.
In the gist below you find timestamped logs of the native libraries being loaded. Without having looked at the loader sources I am surprised to find that more time is spent in loading api-ms-win-crt-*
https://gist.github.com/edwinRNDR/676ea1a75548b31edc07cd699010f75e
Please try again with 1.5.5-SNAPSHOT: http://bytedeco.org/builds/
I updated the gist with the logs for 1.5.5-SNAPSHOT. My observation is that it takes about the same amount of time to load as 1.5.4, but it seems to report less library load failures.
Since FFmpeg is compiled with GCC, it doesn't need those DLLs from MSVC, so you could exclude from your class path the JAR files for javacpp-platform
.
I am not entirely sure how I should do that, the javacpp platform jars do not seem to be on the classpath?
So, where are they getting loaded from? Maybe you should add it, and that's the problem.
Adding javacpp-platform brings the loading time down to 2.5 seconds, which is an improvement but it is still consistently a second more than 1.5.3. I updated the gist with the log (It is the file at the bottom)
Adding javacpp-platform to 1.5.3 seems to make it 250ms faster but that could be noise in my measurements.
Well, this isn't happening here. I've just tested this on my installation of Windows 10, and 4.2.2-1.5.3 takes about 1200 ms, 4.3.1-1.5.4, about 1500 ms, and 4.3.1-1.5.5-SNAPSHOT, about 700 ms. If you figure out what's special about your machine, please let me know!
I don't expect much to be special about this machine, but I will test on some machines at the studio to get a better idea of that. I will also test a project that isn't using LWJGL. Hopeful to see that on your end effort was made to reach the opposite effect of what I am seeing.
In any case, avcodec is failing to load, so this isn't working anyway, correct?
This project setup plays videos without a problem using 1.5.3/1.5.4/1.5.5-SNAPSHOT and has been used on wide range of computers (even non-windows ones). I don't have system-wide ffmpeg installs on this machine and without adding the platform specific libraries to the runtime class-path it runs into UnsatisfiedLinkError
. I think the errors you see come from attempts to load the library from java.library.path
and other locations first?
If you're talking about MSVC libraries, yes, if you don't have javacpp-platform
it will try to load them from the system.
No, that was in reference to
In any case, avcodec is failing to load, so this isn't working anyway, correct?
I did a bit of testing today on a freshly installed system. In the application that I benchmarked yesterday I still see significant differences between 1.5.3 and 1.5.4/1.5.5-SNAPSHOT. Then I figured also ffmpeg changed from 4.2.2 to 4.3.1 and maybe that library just got heavier?
I tried to make some simpler benchmarks. In one I use the example from the javacpp/ffmpeg repository and in the other I try to use only Loader.load
. The benchmarks and code can be found here: https://github.com/edwinRNDR/javacpp-ffmpeg-benchmarks. I am not exactly sure what to conclude from this and I feel like I am wasting time for two at this point :) However, in both my benchmarks 1.5.3 is slightly quicker (I ran the benchmarks multiple times for each of the versions and picked what felt like the average behavior)
According to your new numbers, they all take less than 1 second to load, right? So, what's the issue? Are you sure you're running the exact same binaries on all your machines? Did you try to create an uber JAR and copy it manually to be really sure it's not caused by some network issue? And all your Windows home directories are local, right? Nothing runs on the network, correct? If you're not sure, try to unplug any ethernet cables and disable all wireless connections just to make sure during your tests.
My assumptions may be a bit too vague. Let me outline how I got here.
The original problem was that it took 7 seconds between my first call to a function in the ffmpeg library and a given point X in the video decoding process using javacpp/ffmpeg 4.3.1-1.5.4. That turned out to be PEBCAK as I didn't include the javacpp platform libraries. After including those libraries the time to reach point X is reduced to 2.5 seconds, I also tried 4.3.1-1.5.5-SNAPSHOT which gives me that same 2.5 seconds figure. However, when I switch to javacpp/ffmpeg 4.2.2-1.5.3 it takes 1.5 seconds to reach point X.
At this point the original issue is resolved. But I still see a 1 second difference between 1.5.3 and 1.5.4/1.5.5-SNAPSHOT and I am trying to figure out where that comes from.
So here it gets hairy, and outside of the scope of the original issue. I made the assumption that problem was caused by overhead in the library loader only. I set up a new machine (only to rule out external factors to be in my way) and built a benchmark in attempts to see that overhead. In the end all I can see is that the benchmark appears to run faster against 1.5.3. But, is this because the loader has gotten more overhead or the ffmpeg got heavier to load, I don't know. I also don't know if that overhead can somehow accumulate into that larger difference in my original test. So there is no remaining issue, but just a question for you: What do you read from that LoadClasses
benchmark?
1.5.5-SNAPSHOT should be faster than 1.5.3, so I still think there's something odd about your Windows machines.
I am willing to entertain that but I can't find the reasons to support that thought. Let's try this the other way around: what has changed in 1.5.5-SNAPSHOT that should make it faster than 1.5.3?
https://github.com/bytedeco/javacpp/commit/2ee94b8317ec8e5009950384e3114f546ab094b5
BTW, can you try to set the java.library.path
system property to the empty string by running your program with something like java -Djava.library.path= ...
or with set _JAVA_OPTIONS=-Djava.library.path=
before launching your application just to make sure that this issue is not related to the content of the system PATH?
Could you give this another try with JavaCPP 1.5.5?
As reported by @JimmySimard at https://github.com/bytedeco/javacv/issues/1638, the same thing appears to occur with OpenCV for some users.
I've done some further optimizations in commit https://github.com/bytedeco/javacpp/commit/e8b5734f7d0469478f399bb58e0fd3cfe4af1906 that should pretty much fix any regression in loading time on Windows.
Please give it a try with the snapshots: http://bytedeco.org/builds/