Repository: paritytech/substrate
File: utils/frame/benchmarking-cli/src/storage/read.rs (Rust)

Code before:
impl StorageCmd {
	/// Benchmarks the time it takes to read a single Storage item.
	/// Uses the latest state that is available for the given client.
	pub(crate) fn bench_read<B, BA, C>(&self, client: Arc<C>) -> Result<BenchRecord>
	where
		C: UsageProvider<B> + StorageProvider<B, BA>,
		B: BlockT + Debug,
		BA: ClientBackend<B>,
		<<B as BlockT>::Header as HeaderT>::Number: From<u32>,
	{
		let mut record = BenchRecord::default();
		let block = BlockId::Number(client.usage_info().chain.best_number);

		info!("Preparing keys from block {}", block);
		// Load all keys and randomly shuffle them.
		let empty_prefix = StorageKey(Vec::new());
		let mut keys = client.storage_keys(&block, &empty_prefix)?;
		let (mut rng, _) = new_rng(None);
		keys.shuffle(&mut rng);

		let mut child_nodes = Vec::new();
		// Interesting part here:
		// Read all the keys in the database and measure the time it takes to access each.
		info!("Reading {} keys", keys.len());
		for key in keys.as_slice() {
			if self.params.include_child &&
				key.as_ref().starts_with(DEFAULT_CHILD_STORAGE_KEY_PREFIX)
			{
				// child tree key
				let trie_id = key
					.as_ref()
					.strip_prefix(DEFAULT_CHILD_STORAGE_KEY_PREFIX)
					.expect("Checked above to exist");
				let info = ChildInfo::new_default(trie_id);
				let child_keys = client.child_storage_keys(&block, &info, &empty_prefix)?;
				for ck in child_keys {
					child_nodes.push((ck.clone(), info.clone()));
				}
			} else {
				// regular key
				let start = Instant::now();
				let v = client
					.storage(&block, &key)
					.expect("Checked above to exist")
					.ok_or("Value unexpectedly empty")?;
				record.append(v.0.len(), start.elapsed())?;
			}
		}

		if self.params.include_child {
			child_nodes.shuffle(&mut rng);

Review comment (suggestion):
Usual way of getting child_info is:
```
match ChildType::from_prefixed_key(storage_key) {
				Some((ChildType::ParentKeyId, storage_key)) =>
					Ok(ChildInfo::new_default(storage_key)),
				None => Err(Error::Backend("Invalid child storage key.".to_string())),
			}
```

Code after:
	/// Benchmarks the time it takes to read a single Storage item.
	/// Uses the latest state that is available for the given client.
	pub(crate) fn bench_read<B, BA, C>(&self, client: Arc<C>) -> Result<BenchRecord>
	where
		C: UsageProvider<B> + StorageProvider<B, BA>,
		B: BlockT + Debug,
		BA: ClientBackend<B>,
		<<B as BlockT>::Header as HeaderT>::Number: From<u32>,
	{
		let mut record = BenchRecord::default();
		let block = BlockId::Number(client.usage_info().chain.best_number);

		info!("Preparing keys from block {}", block);
		// Load all keys and randomly shuffle them.
		let empty_prefix = StorageKey(Vec::new());
		let mut keys = client.storage_keys(&block, &empty_prefix)?;
		let (mut rng, _) = new_rng(None);
		keys.shuffle(&mut rng);

		let mut child_nodes = Vec::new();
		// Interesting part here:
		// Read all the keys in the database and measure the time it takes to access each.
		info!("Reading {} keys", keys.len());
		for key in keys.as_slice() {
			match (self.params.include_child_trees, self.is_child_key(key.clone().0)) {
				(true, Some(info)) => {
					// child tree key
					let child_keys = client.child_storage_keys(&block, &info, &empty_prefix)?;
					for ck in child_keys {
						child_nodes.push((ck.clone(), info.clone()));
					}
				},
				_ => {
					// regular key
					let start = Instant::now();
					let v = client
						.storage(&block, &key)
						.expect("Checked above to exist")
						.ok_or("Value unexpectedly empty")?;
					record.append(v.0.len(), start.elapsed())?;
				},
			}
		}

		if self.params.include_child_trees {
			child_nodes.shuffle(&mut rng);

			info!("Reading {} child keys", child_nodes.len());
			for (key, info) in child_nodes.as_slice() {
				let start = Instant::now();
				let v = client