Skip to content

Conversation

@xunilrj
Copy link
Contributor

@xunilrj xunilrj commented Oct 16, 2025

Description

This PR continues the optimisation of contract calls on top of #7455. Now the contract method selector is optimised. Ideally, the method selection would just be a match and we would let the compiler generate the best code.

But we are not there yet. So, for now, we are going to first test the called method length. And based on its length we are going to check the whole string. Something like:

if called_method.len() == 5 {
    if called_method == "abcde" {
        ...
    }
    if called_method == "fghij" {
        ...
    }
}

if called_method.len() == 10 {
    if called_method == "..." {
        ....
    }
}

This alone reduces gas a lot.
To understand why match_expressions_all gas usage is much worse see below.

Test Before After Percentage
should_pass/empty_fields_in_storage_struct (test.toml)::test_read_write_bytes 17533 12080 31.10%
should_pass/empty_fields_in_storage_struct (test.toml)::test_read_write_map 13986 8502 39.21%
should_pass/empty_fields_in_storage_struct (test.toml)::test_read_write_vec 29288 12797 56.31%
should_pass/language/associated_const_abi (test.toml)::test 7817 4547 41.83%
should_pass/language/associated_const_abi_multiple (test.toml)::test 2097 1511 27.94%
should_pass/language/associated_const_in_decls_of_other_constants (test.toml)::test 709 537 24.26%
should_pass/language/contract_ret_intrinsic (test.toml)::test 1809 1465 19.02%
should_pass/language/match_expressions_all (test.toml) 764 3708 -385.34%
should_pass/language/pusha_popa_multiple_defreg (test.toml)::incorrect_pusha_popa 624 451 27.72%
should_pass/language/raw_identifiers (test.error_type.toml)::test 1075 903 16.00%
should_pass/language/raw_identifiers (test.toml)::test 1075 903 16.00%
should_pass/language/references/mutability_of_references_memcpy_bug (test.toml)::test 1203 1031 14.30%
should_pass/language/slice/slice_contract (test.toml)::test_success 1145 920 19.65%
should_pass/language/string_slice/string_slice_contract (test.toml)::test_success 1322 1079 18.38%
should_pass/stdlib/storage_vec_insert (test.toml)::test_test_function 3831 3669 4.23%
should_pass/storage_element_key_modification (test.toml)::test_storage_key_address 1138 943 17.14%
should_pass/storage_element_key_modification (test.toml)::test_storage_key_modification 757 465 38.57%
should_pass/storage_slot_key_calculation (test.toml)::test 2979 2785 6.51%
should_pass/superabi_contract_calls (test.toml)::tests 1812 1310 27.70%
should_pass/superabi_supertrait_external_call (test.toml) 95 76 20.00%
should_pass/superabi_supertrait_same_methods (test.toml)::tests 936 634 32.26%
should_pass/test_abis/abi_impl_methods_callable (test.toml)::tests 772 599 22.41%
should_pass/test_abis/contract_abi-auto_impl (test.toml)::tests 772 599 22.41%
should_pass/unit_tests/aggr_indexing (test.toml)::test1 5443 4282 21.33%
should_pass/unit_tests/contract-multi-contract-calls (test.toml)::test_contract_2_call 804 631 21.52%
should_pass/unit_tests/contract-multi-contract-calls (test.toml)::test_contract_call 807 634 21.44%
should_pass/unit_tests/contract-multi-contract-calls (test.toml)::test_contract_multi_call 1592 1246 21.73%
should_pass/unit_tests/contract_multi_test (test.toml)::test_fail 808 635 21.41%
should_pass/unit_tests/contract_multi_test (test.toml)::test_success 806 633 21.46%
should_pass/unit_tests/script-contract-calls (test.toml)::test_contract_call 736 563 23.51%
should_pass/unit_tests/workspace_test (test.toml)::test_fail 808 635 21.41%
should_pass/unit_tests/workspace_test (test.toml)::test_success 807 634 21.44%

Radix Trie

This PR also turns off the radix trie optimisation at sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_match_expression.rs. I am not 100% sure of its correctness and heuristics.

We need a better way to decide when not to use it. One of the examples where the generated code is worse is when all strings are very similar. For example: get_a , get_b. The generated trie will first test its length. Both have length 5. Not much was gained. Then it tests if for get_, which makes sense as it is the common substring. And the last step will test for a or b.

The issue is that all branches and jumps of the last step are not worthy to test just one character. Is probably cheaper to just test the whole string for each option.

In the end, we need a better heuristic to determine when to use this optimisation.

Checklist

  • I have linked to any relevant issues.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have updated the documentation where relevant (API docs, the reference, and the Sway book).
  • I have added tests that prove my fix is effective or that my feature works.
  • I have added (or requested a maintainer to add) the necessary Breaking* or New Feature labels where relevant.
  • I have done my best to ensure that my PR adheres to the Fuel Labs Code Review Standards.
  • I have requested a review from the relevant team or maintainers.

@codspeed-hq
Copy link

codspeed-hq bot commented Oct 16, 2025

CodSpeed Performance Report

Merging #7458 will not alter performance

Comparing xunilrj/improve-contract-call-3 (7a1f2ea) with master (e6f2ac8)

Summary

✅ 25 untouched

@xunilrj xunilrj force-pushed the xunilrj/improve-contract-call-3 branch from 048a736 to 5f2f098 Compare October 26, 2025 16:22
@xunilrj xunilrj self-assigned this Oct 26, 2025
@xunilrj xunilrj marked this pull request as ready for review October 27, 2025 15:26
@xunilrj xunilrj requested review from a team as code owners October 27, 2025 15:26
@xunilrj xunilrj force-pushed the xunilrj/improve-contract-call-3 branch from 0ac99b2 to 1598d82 Compare October 31, 2025 17:21
@xunilrj xunilrj requested a review from a team as a code owner November 2, 2025 22:21
@xunilrj xunilrj force-pushed the xunilrj/improve-contract-call-3 branch from 2f3cfa1 to 9265277 Compare November 3, 2025 11:25
@xunilrj xunilrj requested review from a team and tritao November 3, 2025 14:00
@xunilrj xunilrj merged commit 6bca188 into master Nov 4, 2025
46 checks passed
@xunilrj xunilrj deleted the xunilrj/improve-contract-call-3 branch November 4, 2025 02:06
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.

4 participants