Real-Life Benchmark for FUSE's readdir()

Sebastian Stenzel sebastian.stenzel at gmail.com
Fri Jul 9 08:58:56 UTC 2021


Hi,

I wanted to share the results of a benchmark test, that includes several down- and upcalls. First, let me explain, what I'm testing here:

I'm working on a panama-based FUSE binding, mostly for experimental purposes right now, and I'm trying to beat fuse-jnr [1].

While there are some other interesting metrics, such as read/write performance (both sequentially and random access), I focused on directory listings for now. Directory listings are the most complex operation in regards to the number of down- and upcalls:

1. FUSE upcalls readdir and provides a callback function
2. java downcalls the callback for each item in the directory
3. FUSE upcalls getattr for each item (no longer required with "readdirplus" in FUSE 3.x)
(4. I'm testing on macOS, which introduces additional noise (such as readxattr and trying to access files that I didn't report in readdir))

So, what I'm testing is essentially this: `Files.list(Path.of("/Volumes/foo")).close();` with the volume reporting eight files [2]. When mounting with debug logs enabled, I can see that the exact same operations in the same order are invoked on both fuse-jnr and fuse-panama. One single dir listing results in 2 readdir upcalls, 10 callback downcalls, 16 getattr upcalls. There are also 8 getxattr calls and 16 lookup calls, however they don't reach Java, as the FUSE kernel knows they are not implemented.

Long story short, here are the results:

```
Benchmark                        Mode  Cnt    Score   Error  Units
BenchmarkTest.testListDirJnr     avgt    5   66,569 ± 3,128  us/op
BenchmarkTest.testListDirPanama  avgt    5  189,340 ± 4,275  us/op
```

I've been using panama snapshot at commit 42e03fd7c6a built with: `configure --with-boot-jdk=/Library/Java/JavaVirtualMachines/adoptopenjdk-16.jdk/Contents/Home/ --with-native-debug-symbols=none --with-debug-level=release --with-libclang=/usr/local/opt/llvm --with-libclang-version=12`

I can't tell where this overhead comes from. Maybe creating a newConfinedScope() during each upcall [3] is "too much"? Maybe JNR is just negligently skipping some memory boundary checks to be faster. The results are not terrible, but I'd hoped for something better.

Sebastian

[1] https://github.com/SerCeMan/jnr-fuse <https://github.com/SerCeMan/jnr-fuse>
[2] https://github.com/skymatic/fuse-panama/blob/develop/src/test/java/de/skymatic/fusepanama/examples/HelloPanamaFileSystem.java#L139-L146 <https://github.com/skymatic/fuse-panama/blob/develop/src/test/java/de/skymatic/fusepanama/examples/HelloPanamaFileSystem.java#L139-L146>
[3] https://github.com/skymatic/fuse-panama/blob/769347575863861063a2347a42b2cbaadb5eacef/src/main/java/de/skymatic/fusepanama/FuseOperations.java#L67-L71 <https://github.com/skymatic/fuse-panama/blob/769347575863861063a2347a42b2cbaadb5eacef/src/main/java/de/skymatic/fusepanama/FuseOperations.java#L67-L71>


More information about the panama-dev mailing list