Skip to content

Commit

Permalink
[move stdlib] minimize calls to length in vector functions
Browse files Browse the repository at this point in the history
Calling length in a loop is less gas and wall time efficient than calling it once and using a simple loop.
  • Loading branch information
sblackshear committed Dec 7, 2024
1 parent 24850f3 commit 3177515
Show file tree
Hide file tree
Showing 8 changed files with 32 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ task 1, lines 9-22:
//# publish
created: object(1,0)
mutated: object(0,2)
gas summary: computation_cost: 1000000, storage_cost: 5563200, storage_rebate: 0, non_refundable_storage_fee: 0
gas summary: computation_cost: 1000000, storage_cost: 5791200, storage_rebate: 0, non_refundable_storage_fee: 0

task 2, lines 24-28:
//# programmable --sender A --inputs 100000 @A
Expand Down
6 changes: 2 additions & 4 deletions crates/sui-framework/docs/move-stdlib/vector.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,10 +312,8 @@ Pushes all of the elements of the <code>other</code> vector into the <code>lhs</
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/vector.md#0x1_vector_append">append</a>&lt;Element&gt;(lhs: &<b>mut</b> <a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;Element&gt;, <b>mut</b> other: <a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;Element&gt;) {
other.<a href="../move-stdlib/vector.md#0x1_vector_reverse">reverse</a>();
<b>while</b> (other.<a href="../move-stdlib/vector.md#0x1_vector_length">length</a>() != 0) lhs.<a href="../move-stdlib/vector.md#0x1_vector_push_back">push_back</a>(other.<a href="../move-stdlib/vector.md#0x1_vector_pop_back">pop_back</a>());
other.<a href="../move-stdlib/vector.md#0x1_vector_destroy_empty">destroy_empty</a>();
<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/vector.md#0x1_vector_append">append</a>&lt;Element&gt;(lhs: &<b>mut</b> <a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;Element&gt;, other: <a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;Element&gt;) {
other.do!(|e| lhs.<a href="../move-stdlib/vector.md#0x1_vector_push_back">push_back</a>(e));
}
</code></pre>

Expand Down
8 changes: 3 additions & 5 deletions crates/sui-framework/packages/move-stdlib/sources/vector.move
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,8 @@ public fun reverse<Element>(v: &mut vector<Element>) {
}

/// Pushes all of the elements of the `other` vector into the `lhs` vector.
public fun append<Element>(lhs: &mut vector<Element>, mut other: vector<Element>) {
other.reverse();
while (other.length() != 0) lhs.push_back(other.pop_back());
other.destroy_empty();
public fun append<Element>(lhs: &mut vector<Element>, other: vector<Element>) {
other.do!(|e| lhs.push_back(e));
}

/// Return `true` if the vector `v` has no elements and `false` otherwise.
Expand Down Expand Up @@ -185,7 +183,7 @@ public macro fun destroy<$T>($v: vector<$T>, $f: |$T|) {
public macro fun do<$T>($v: vector<$T>, $f: |$T|) {
let mut v = $v;
v.reverse();
while (v.length() != 0) $f(v.pop_back());
v.length().do!(|_| $f(v.pop_back()));
v.destroy_empty();
}

Expand Down
10 changes: 10 additions & 0 deletions crates/sui-framework/packages/move-stdlib/tests/vector_tests.move
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ fun append_empties_is_empty() {
assert!(v1.is_empty());
}

#[test]
fun append_singletons() {
let mut v1 = vector[0];
let v2 = vector[1];
v1.append(v2);
assert!(v1.length() == 2);
assert!(v1[0] == 0);
assert!(v1[1] == 1);
}

#[test]
fun append_respects_order_empty_lhs() {
let mut v1 = vector[];
Expand Down
Binary file modified crates/sui-framework/packages_compiled/move-stdlib
Binary file not shown.
Binary file modified crates/sui-framework/packages_compiled/sui-framework
Binary file not shown.
1 change: 1 addition & 0 deletions crates/sui-protocol-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ const MAX_PROTOCOL_VERSION: u64 = 70;
// Enable probing for accepted rounds in round prober in testnet
// Add new gas model version to update charging of native functions.
// Add std::uq64_64 module to Move stdlib.
// Improve gas/wall time efficiency of some Move stdlib vector functions

#[derive(Copy, Clone, Debug, Hash, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct ProtocolVersion(u64);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,56 +240,56 @@ validators:
next_epoch_worker_address: ~
extra_fields:
id:
id: "0xcebe975bb1b8e53e6af39513515419a9a7c689693f249740e43689f6aeda32ba"
id: "0xd336ec43763c7e6cb1a58af9e463220f7f28afb4bf5ac683e53c87ffe1df0a4c"
size: 0
voting_power: 10000
operation_cap_id: "0x2e4b656205b19fc58169a879f3ac919d5299a471693c23c70a93e36f9ae5d4a0"
operation_cap_id: "0x8dab96e36a4870498181e5f793537a9430944acddf495603c6afa93cc37f3889"
gas_price: 1000
staking_pool:
id: "0x9c8b960db18d273e85a80401ca97c09253b3fd82f413d9e355afe9eab0e82858"
id: "0x131722dffbbebd704bf861887766f9b11b8ff4ae88e014b1d343eee977d3b4bc"
activation_epoch: 0
deactivation_epoch: ~
sui_balance: 20000000000000000
rewards_pool:
value: 0
pool_token_balance: 20000000000000000
exchange_rates:
id: "0x705442e06a6805513bbde51a9030bd4725274e8843bd4ad603afcc48fedda000"
id: "0x87e0379fe286c022d350f16878363aa19706f483aabf4d5b28cbe64b737bfbb9"
size: 1
pending_stake: 0
pending_total_sui_withdraw: 0
pending_pool_token_withdraw: 0
extra_fields:
id:
id: "0x4ad2829c103ec2f25d4a2d8138fba5111ad6b5289a3ecddedf5ac4e030aae877"
id: "0x4391b75bfd492755194154168d934d80fce1c2b661b08de7eee4c353ab2c2302"
size: 0
commission_rate: 200
next_epoch_stake: 20000000000000000
next_epoch_gas_price: 1000
next_epoch_commission_rate: 200
extra_fields:
id:
id: "0xbfb962637c22ef853d4acb95ebfb811996d6ec8a27546e3d3f9e52c5c2713e82"
id: "0x152af272a7a45cc3216bc6355b7dcfd0e4ed47271b4821d4af3566fb87e957fd"
size: 0
pending_active_validators:
contents:
id: "0xb33ed5bbf74e91ab4d04031ec1ab518e780a7c3f3a366cd192d1cd853bfbc8be"
id: "0xa0aa2ed79148441eba1d8cf0c080a6136a55376c58e9451b4c5a2507d49e2f80"
size: 0
pending_removals: []
staking_pool_mappings:
id: "0xedbabcc635a1f34d5739154e11f258cea3e8bf15115f89508c5939b4ef577291"
id: "0xb31a46b712d3bce7378b42f74d5514b46d2d5532a267dad65d6627b638acd908"
size: 1
inactive_validators:
id: "0xb8d534ef50875b43804861d8e5dbf4a06a5f4c963cc0ae8c659c87dfdda4c43f"
id: "0x10b278cfadb57996d8c63c0c15c1aa9656d3ff2e0c6384fdc006b6a9b5a37597"
size: 0
validator_candidates:
id: "0xa112fa6e91b7ce533851360d8368830407cdc9bf3599fa243d5204d97fe42711"
id: "0x4f013d2a81f8c361a9411df03397dc5cdae04023c68fe2b15a1334cc7fab78c4"
size: 0
at_risk_validators:
contents: []
extra_fields:
id:
id: "0x410bd3fc4e5000f94e8b70851d0aa23cb611154e3046cb06a4d8023c39fbb70b"
id: "0xd8d77e98c2913975291b41b79954b1f679f0193ddecde2158b6fd899ebecf93d"
size: 0
storage_fund:
total_object_storage_rebates:
Expand All @@ -306,7 +306,7 @@ parameters:
validator_low_stake_grace_period: 7
extra_fields:
id:
id: "0x5e42d5798306b3e67b20ead164d54956558be121660350ca2447a08422bed768"
id: "0x6dd6b96ea34c02dc9ca19574bd3689c7680b7910a34ace35b5960d62b2f89f24"
size: 0
reference_gas_price: 1000
validator_report_records:
Expand All @@ -320,7 +320,7 @@ stake_subsidy:
stake_subsidy_decrease_rate: 1000
extra_fields:
id:
id: "0xb001553979b3d2613e00064f5c8a03c94879530f7faf9e3641c86ef5d02df396"
id: "0xf6c77f67f7f190260b807bbcaef13dc3a4054fb7f85927c969d5b0d50c162c23"
size: 0
safe_mode: false
safe_mode_storage_rewards:
Expand All @@ -332,5 +332,6 @@ safe_mode_non_refundable_storage_fee: 0
epoch_start_timestamp_ms: 10
extra_fields:
id:
id: "0x91168b5f93153d5b24b67b76d4e0dd4553a4bca86ce596e948c0bdefe7c56715"
id: "0xa2545fec3666cb6bbd9099d52f2e461d4d679511ed481f8a95f4c99bfbaaf6dd"
size: 0

0 comments on commit 3177515

Please sign in to comment.