Skip to content

perf(android): resolve primitive and String call sites without the overload matcher - #124

Open
ammarahm-ed wants to merge 1 commit into
perf/jni-04-jnienv-cachefrom
perf/jni-05-direct-signature
Open

ammarahm-ed wants to merge 1 commit into
perf/jni-04-jnienv-cachefrom
perf/jni-05-direct-signature

Conversation

@ammarahm-ed

Copy link
Copy Markdown
Collaborator

MethodCallback ran the metadata-first overload match on every call, even for a method with one candidate: it parsed the signature into a vector<string>, called napi_typeof or inspected each argument, and built a std::vector<jclass> of parameter classes. For a method whose parameters are all primitives or String, none of that can change the outcome, so it is now resolved once per call site.

On the first call, MatchDirectSignature turns the single candidate's signature into a string of parameter kinds (I, D, Z, ..., T for String) and caches it on MethodCallbackData. Each call then compares the argument types to that string and goes straight to CallJavaMethod with the same match result the full matcher gave:

  • all arguments fit: the entry is used as unambiguous;
  • an argument is null or undefined: the entry is kept, not unambiguous;
  • an argument has the wrong type: the entry is dropped and reflection resolves the call.

A signature with an object or array parameter, or a call that passes an object, array or function, still goes through the full matcher. Both the Node-API and the direct runtime get the change.

Results

V8 release build on a Sony SO-01M (Android 11, arm64), AOT-compiled with cmd package compile -m speed. One warm-up launch is discarded, then 5 launches; values are the median ns per call.

Case Node-API before after Δ Direct before after Δ
Void Method on instance 694 671 -3% 654 575 -12%
Void Static Method 355 346 -2% 330 303 -8%
multiply(a, b) 749 510 -32% 824 537 -35%
Instance add(a, b) 1,097 855 -22% 1,105 799 -28%
Pass an Int 607 436 -28% 636 414 -35%
Pass a Double 593 428 -28% 621 434 -30%
Pass a Boolean 724 500 -31% 633 446 -30%
Pass a String 1,073 703 -34% 1,168 665 -43%
Pass and return string 1,850 1,211 -35% 2,059 1,144 -44%

Rows this change does not touch moved by up to ±15% between runs (array and object returns by up to ±26%), which is this device's noise floor; only changes well beyond that are attributable.

All cases
Case Node-API before after Δ Direct before after Δ
Void Method on instance 694 671 -3% 654 575 -12%
Field on instance 819 824 +1% 821 860 +5%
Int Field on instance 381 380 -0% 369 368 -0%
Get Static Field 866 834 -4% 816 879 +8%
Void Static Method 355 346 -2% 330 303 -8%
multiply(a, b) 749 510 -32% 824 537 -35%
Pass and return string 1,850 1,211 -35% 2,059 1,144 -44%
Return a String 873 812 -7% 890 794 -11%
Return an Int 354 339 -4% 351 312 -11%
Pass a String 1,073 703 -34% 1,168 665 -43%
Return a Boolean 342 334 -2% 333 307 -8%
Return a Double 462 409 -12% 440 386 -12%
Pass an Int 607 436 -28% 636 414 -35%
Pass a Double 593 428 -28% 621 434 -30%
Pass a Boolean 724 500 -31% 633 446 -30%
Return an Int Array 27,509 28,417 +3% 17,994 18,199 +1%
Pass an Int Array 3,273 3,356 +3% 4,036 4,116 +2%
Return a String Array 27,111 29,365 +8% 19,576 19,965 +2%
Pass a String Array 5,420 5,624 +4% 6,872 6,732 -2%
Return a Double Array 27,135 28,102 +4% 20,574 19,561 -5%
Pass a Double Array 3,094 3,249 +5% 3,896 3,941 +1%
Return a Boolean Array 25,343 27,043 +7% 18,770 18,685 -0%
Pass a Boolean Array 2,926 3,162 +8% 3,757 3,793 +1%
Int Array[0] read 366 366 +0% 239 259 +9%
String Array[0] read 783 771 -1% 685 684 -0%
Double Array[0] read 446 444 -0% 343 362 +5%
Boolean Array[0] read 341 349 +2% 236 253 +7%
Int Array[0] write 458 452 -1% 375 377 +1%
String Array[0] write 1,128 1,155 +2% 1,060 1,077 +2%
Double Array[0] write 467 476 +2% 383 386 +1%
Boolean Array[0] write 458 478 +4% 388 390 +1%
Return a Date Object 31,058 30,484 -2% 24,197 24,658 +2%
Pass a Date Object 3,871 3,931 +2% 3,512 3,597 +2%
Invoke void callback 7,670 7,254 -5% 6,940 6,884 -1%
Instance add(a, b) 1,097 855 -22% 1,105 799 -28%
Pass and return non-ASCII string 1,870 1,228 -34% 2,083 1,141 -45%
Pass and return 1KB string 5,698 5,065 -11% 6,066 4,997 -18%
Return a Char 396 373 -6% 383 341 -11%
Return this 1,646 1,248 -24% 1,549 1,279 -17%
Return a new object 30,520 31,356 +3% 24,424 23,765 -3%
Call a method on a new object 38,321 39,072 +2% 33,041 33,952 +3%
Pass a 16 Int Array 4,350 4,558 +5% 5,313 5,152 -3%
Pass a 16 Double Array 4,882 5,130 +5% 5,733 5,796 +1%
Invoke int callback 10,264 10,264 -0% 10,623 10,772 +1%
Invoke string callback 8,652 8,610 -0% 8,281 8,336 +1%
Native heap after run (MB) 270 MB 257 MB -5% 204 MB 183 MB -10%

Only V8 was built and run.

@coderabbitai

coderabbitai Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ac3d35d0-cb82-44d8-b05d-dcbc2316fcc0

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@ammarahm-ed
ammarahm-ed added this pull request to stack #121 November 9, 2026 06:32

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant