From d1386de632333e936b5bed63510c5d89d6cd18b4 Mon Sep 17 00:00:00 2001 From: Alan Paxton Date: Thu, 22 Feb 2024 15:01:55 -0800 Subject: [PATCH] Java FFI blog post - Post-publication issues with images (2) (#12372) Summary: Replace unreliable-in-chrome PDF w/PNG of same graph jmh-result-pinnable-vs-output-plot.pdf is showing as thumbnail on Chrome, rendering OK on Safari for some; I have converted it to PNG in the hope that will display correctly in all environments. Pull Request resolved: https://github.com/facebook/rocksdb/pull/12372 Reviewed By: cbi42 Differential Revision: D54076718 Pulled By: jowlyzhang fbshipit-source-id: 2eff995f0239ab7850a40063d841380738953533 --- ...24-02-20-foreign-function-interface.markdown | 2 +- .../jmh-result-pinnable-vs-output-plot.pdf | Bin 18048 -> 0 bytes .../jmh-result-pinnable-vs-output-plot.png | Bin 0 -> 11263 bytes 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 docs/static/images/jni-ffi/jmh-result-pinnable-vs-output-plot.pdf create mode 100644 docs/static/images/jni-ffi/jmh-result-pinnable-vs-output-plot.png diff --git a/docs/_posts/2024-02-20-foreign-function-interface.markdown b/docs/_posts/2024-02-20-foreign-function-interface.markdown index e93710df13..da1dd26eaf 100644 --- a/docs/_posts/2024-02-20-foreign-function-interface.markdown +++ b/docs/_posts/2024-02-20-foreign-function-interface.markdown @@ -190,7 +190,7 @@ q "select Benchmark,Score from ./plot/jmh-result-fixed.csv where \"Param: keyCou The second method call over the FFI boundary to release a pinnable slice has a cost. We compared the `ffiGetOutputSlice()` and `ffiGetPinnableSlice()` benchmarks in order to examine this cost. We ran it with a fixed ky size (128 bytes); the key size is likely to be pretty much irrelevant anyway; we varied the value size read from 16 bytes to 16k, and we found a crossover point between 1k and 4k for performance: -![Plot](/static/images/jni-ffi/jmh-result-pinnable-vs-output-plot.pdf) +![Plot](/static/images/jni-ffi/jmh-result-pinnable-vs-output-plot.png) - `ffiGetOutputSlice()` is faster when values read are 1k in size or smaller. The cost of an extra copy in the C++ side from the pinnable slice buffer into the supplied buffer allocated by Java Foreign Memory API is less than the cost of the extra call to release a pinnable slice. - `ffiGetPinnableSlice()` is faster when values read are 4k in size, or larger. Consistent with intuition, the advantage grows with larger read values. diff --git a/docs/static/images/jni-ffi/jmh-result-pinnable-vs-output-plot.pdf b/docs/static/images/jni-ffi/jmh-result-pinnable-vs-output-plot.pdf deleted file mode 100644 index f958eb08ac262e9c02a84a3e61af931edc119db5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18048 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 ZE0O=KVDSAO;45i<*9j;$h~qb%_k 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