javacpp icon indicating copy to clipboard operation
javacpp copied to clipboard

Loading native libraries on Windows 10 takes a long time

Open edwinRNDR opened this issue 4 years ago • 21 comments

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

edwinRNDR avatar Jan 31 '21 09:01 edwinRNDR

Please try again with 1.5.5-SNAPSHOT: http://bytedeco.org/builds/

saudet avatar Jan 31 '21 11:01 saudet

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.

edwinRNDR avatar Jan 31 '21 13:01 edwinRNDR

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.

saudet avatar Jan 31 '21 13:01 saudet

I am not entirely sure how I should do that, the javacpp platform jars do not seem to be on the classpath?

image

edwinRNDR avatar Jan 31 '21 13:01 edwinRNDR

So, where are they getting loaded from? Maybe you should add it, and that's the problem.

saudet avatar Jan 31 '21 19:01 saudet

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.

edwinRNDR avatar Jan 31 '21 21:01 edwinRNDR

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!

saudet avatar Feb 01 '21 03:02 saudet

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.

edwinRNDR avatar Feb 01 '21 06:02 edwinRNDR

In any case, avcodec is failing to load, so this isn't working anyway, correct?

saudet avatar Feb 01 '21 07:02 saudet

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?

edwinRNDR avatar Feb 01 '21 08:02 edwinRNDR

If you're talking about MSVC libraries, yes, if you don't have javacpp-platform it will try to load them from the system.

saudet avatar Feb 01 '21 11:02 saudet

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)

edwinRNDR avatar Feb 01 '21 20:02 edwinRNDR

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.

saudet avatar Feb 01 '21 23:02 saudet

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?

edwinRNDR avatar Feb 02 '21 08:02 edwinRNDR

1.5.5-SNAPSHOT should be faster than 1.5.3, so I still think there's something odd about your Windows machines.

saudet avatar Feb 02 '21 08:02 saudet

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?

edwinRNDR avatar Feb 02 '21 09:02 edwinRNDR

https://github.com/bytedeco/javacpp/commit/2ee94b8317ec8e5009950384e3114f546ab094b5

saudet avatar Feb 02 '21 09:02 saudet

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?

saudet avatar Feb 12 '21 04:02 saudet

Could you give this another try with JavaCPP 1.5.5?

saudet avatar Apr 11 '21 09:04 saudet

As reported by @JimmySimard at https://github.com/bytedeco/javacv/issues/1638, the same thing appears to occur with OpenCV for some users.

saudet avatar May 06 '21 02:05 saudet

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/

saudet avatar Jan 25 '22 01:01 saudet