Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit affa012

Browse files
edg-lfannyguthmann
authored andcommitted
perf: refactor substract_mappings and friends to avoid clones (#1023)
* refactor substract_mappings and friends to avoid clones of the whole hashmap * another opt * dont use deref * fix deref again * no need for contains_key * oops
1 parent c1b1272 commit affa012

File tree

3 files changed

+52
-45
lines changed

3 files changed

+52
-45
lines changed

src/state/cached_state.rs

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use crate::{
77
services::api::contract_classes::compiled_class::CompiledClass,
88
state::StateDiff,
99
utils::{
10-
get_erc20_balance_var_addresses, subtract_mappings, to_cache_state_storage_mapping,
11-
Address, ClassHash,
10+
get_erc20_balance_var_addresses, subtract_mappings, subtract_mappings_keys,
11+
to_cache_state_storage_mapping, Address, ClassHash,
1212
},
1313
};
1414
use cairo_vm::felt::Felt252;
@@ -281,32 +281,24 @@ impl<T: StateReader> State for CachedState<T> {
281281
self.update_initial_values_of_write_only_accesses()?;
282282

283283
let mut storage_updates = subtract_mappings(
284-
self.cache.storage_writes.clone(),
285-
self.cache.storage_initial_values.clone(),
284+
&self.cache.storage_writes,
285+
&self.cache.storage_initial_values,
286286
);
287287

288288
let storage_unique_updates = storage_updates.keys().map(|k| k.0.clone());
289289

290-
let class_hash_updates: Vec<_> = subtract_mappings(
291-
self.cache.class_hash_writes.clone(),
292-
self.cache.class_hash_initial_values.clone(),
293-
)
294-
.keys()
295-
.cloned()
296-
.collect();
290+
let class_hash_updates = subtract_mappings_keys(
291+
&self.cache.class_hash_writes,
292+
&self.cache.class_hash_initial_values,
293+
);
297294

298-
let nonce_updates: Vec<_> = subtract_mappings(
299-
self.cache.nonce_writes.clone(),
300-
self.cache.nonce_initial_values.clone(),
301-
)
302-
.keys()
303-
.cloned()
304-
.collect();
295+
let nonce_updates =
296+
subtract_mappings_keys(&self.cache.nonce_writes, &self.cache.nonce_initial_values);
305297

306298
let mut modified_contracts: HashSet<Address> = HashSet::new();
307299
modified_contracts.extend(storage_unique_updates);
308-
modified_contracts.extend(class_hash_updates);
309-
modified_contracts.extend(nonce_updates);
300+
modified_contracts.extend(class_hash_updates.cloned());
301+
modified_contracts.extend(nonce_updates.cloned());
310302

311303
// Add fee transfer storage update before actually charging it, as it needs to be included in the
312304
// calculation of the final fee.

src/state/mod.rs

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -134,25 +134,23 @@ impl StateDiff {
134134
let state_cache = cached_state.cache().to_owned();
135135

136136
let substracted_maps = subtract_mappings(
137-
state_cache.storage_writes.clone(),
138-
state_cache.storage_initial_values.clone(),
137+
&state_cache.storage_writes,
138+
&state_cache.storage_initial_values,
139139
);
140140

141141
let storage_updates = to_state_diff_storage_mapping(substracted_maps);
142142

143-
let address_to_nonce = subtract_mappings(
144-
state_cache.nonce_writes.clone(),
145-
state_cache.nonce_initial_values.clone(),
146-
);
143+
let address_to_nonce =
144+
subtract_mappings(&state_cache.nonce_writes, &state_cache.nonce_initial_values);
147145

148146
let class_hash_to_compiled_class = subtract_mappings(
149-
state_cache.compiled_class_hash_writes.clone(),
150-
state_cache.compiled_class_hash_initial_values.clone(),
147+
&state_cache.compiled_class_hash_writes,
148+
&state_cache.compiled_class_hash_initial_values,
151149
);
152150

153151
let address_to_class_hash = subtract_mappings(
154-
state_cache.class_hash_writes.clone(),
155-
state_cache.class_hash_initial_values,
152+
&state_cache.class_hash_writes,
153+
&state_cache.class_hash_initial_values,
156154
);
157155

158156
Ok(StateDiff {
@@ -193,23 +191,22 @@ impl StateDiff {
193191

194192
let mut storage_updates = HashMap::new();
195193

196-
let addresses: Vec<Address> =
197-
get_keys(self.storage_updates.clone(), other.storage_updates.clone());
194+
let addresses: Vec<&Address> = get_keys(&self.storage_updates, &other.storage_updates);
198195

199196
for address in addresses {
200197
let default: HashMap<Felt252, Felt252> = HashMap::new();
201198
let mut map_a = self
202199
.storage_updates
203-
.get(&address)
200+
.get(address)
204201
.unwrap_or(&default)
205202
.to_owned();
206203
let map_b = other
207204
.storage_updates
208-
.get(&address)
205+
.get(address)
209206
.unwrap_or(&default)
210207
.to_owned();
211208
map_a.extend(map_b);
212-
storage_updates.insert(address, map_a.clone());
209+
storage_updates.insert(address.clone(), map_a.clone());
213210
}
214211

215212
StateDiff {

src/utils.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -230,20 +230,38 @@ where
230230
V: PartialEq + Clone,
231231
{
232232
let val = map.get(key);
233-
!(map.contains_key(key) && (Some(value) == val))
233+
Some(value) != val
234234
}
235235

236-
pub fn subtract_mappings<K, V>(map_a: HashMap<K, V>, map_b: HashMap<K, V>) -> HashMap<K, V>
236+
pub fn subtract_mappings<'a, K, V>(
237+
map_a: &'a HashMap<K, V>,
238+
map_b: &'a HashMap<K, V>,
239+
) -> HashMap<K, V>
237240
where
238241
K: Hash + Eq + Clone,
239242
V: PartialEq + Clone,
240243
{
241244
map_a
242-
.into_iter()
243-
.filter(|(k, v)| contained_and_not_updated(k, v, &map_b))
245+
.iter()
246+
.filter(|(k, v)| contained_and_not_updated(*k, *v, map_b))
247+
.map(|(k, v)| (k.clone(), v.clone()))
244248
.collect()
245249
}
246250

251+
pub fn subtract_mappings_keys<'a, K, V>(
252+
map_a: &'a HashMap<K, V>,
253+
map_b: &'a HashMap<K, V>,
254+
) -> impl Iterator<Item = &'a K>
255+
where
256+
K: Hash + Eq + Clone,
257+
V: PartialEq + Clone,
258+
{
259+
map_a
260+
.iter()
261+
.filter(|(k, v)| contained_and_not_updated(*k, *v, map_b))
262+
.map(|x| x.0)
263+
}
264+
247265
/// Converts StateDiff storage mapping (addresses map to a key-value mapping) to CachedState
248266
/// storage mapping (Tuple of address and key map to the associated value).
249267
pub fn to_cache_state_storage_mapping(
@@ -260,12 +278,12 @@ pub fn to_cache_state_storage_mapping(
260278

261279
// get a vector of keys from two hashmaps
262280

263-
pub fn get_keys<K, V>(map_a: HashMap<K, V>, map_b: HashMap<K, V>) -> Vec<K>
281+
pub fn get_keys<'a, K, V>(map_a: &'a HashMap<K, V>, map_b: &'a HashMap<K, V>) -> Vec<&'a K>
264282
where
265283
K: Hash + Eq,
266284
{
267-
let mut keys1: HashSet<K> = map_a.into_keys().collect();
268-
let keys2: HashSet<K> = map_b.into_keys().collect();
285+
let mut keys1: HashSet<&K> = map_a.keys().collect();
286+
let keys2: HashSet<&K> = map_b.keys().collect();
269287

270288
keys1.extend(keys2);
271289

@@ -647,7 +665,7 @@ mod test {
647665
.into_iter()
648666
.collect::<HashMap<&str, i32>>();
649667

650-
assert_eq!(subtract_mappings(a, b), res);
668+
assert_eq!(subtract_mappings(&a, &b), res);
651669

652670
let mut c = HashMap::new();
653671
let mut d = HashMap::new();
@@ -664,7 +682,7 @@ mod test {
664682
.into_iter()
665683
.collect::<HashMap<i32, i32>>();
666684

667-
assert_eq!(subtract_mappings(c, d), res);
685+
assert_eq!(subtract_mappings(&c, &d), res);
668686

669687
let mut e = HashMap::new();
670688
let mut f = HashMap::new();
@@ -676,7 +694,7 @@ mod test {
676694
f.insert(3, 4);
677695
f.insert(6, 7);
678696

679-
assert_eq!(subtract_mappings(e, f), HashMap::new())
697+
assert_eq!(subtract_mappings(&e, &f), HashMap::new())
680698
}
681699

682700
#[test]

0 commit comments

Comments
 (0)