-
Notifications
You must be signed in to change notification settings - Fork 676
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Contract Examples and Metrics #1829
Comments
For the record, as reported by @k06a when working with eth-bridge the cost of submitting Eth block header (70KiB -- 1200 hashes input) takes 0.1e15 gas which is a lot. The current gas limit of per transaction in 0.2e15. 99% of this gas is JSON parsing and 1% is actual math. JSON parsing is already optimized, it uses hex-encoding for hashes, and does other optimizations. CC @vgrichina |
I'd suggest considering serializing to Borsh on the near node before passing arguments into a smart contract, to keep |
This is an example of gas consumption of near-bridge smart contract,
|
Here is the full testing results, going to summarize them in the next comment:
|
Base gas cost of full noop call is Extra cost of JSON input for an extra character in an argument name e.g. (aa: u32) vs (a: u32) IntegersCost of JSON input of (a: u32) where a=1 is Cost of Borsh input of (a: u32) is StringCost of JSON input of (s: String) where s="" is Cost of JSON output of String where s="" is Cost of Borsh input of (s: String) where s="" is Cost of Borsh output of String where s="" is
|
Extra cost of Borsh per string char argument is higher than with JSON. |
Well it's not about the
vs
|
It might be related to the fact that Borsh deserialization is slower than bincode http://borsh.io/ . Something about the way we are reading slices of bytes is very unoptimal. |
Switched String deserialization with the following: impl BorshDeserialize for String {
#[inline]
fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
let len = u32::deserialize(reader)?;
// TODO(16): return capacity allocation when we have the size of the buffer left from the reader.
let mut result = Vec::with_capacity(hint::cautious::<u8>(len));
let mut i = 0;
let batch_len = 1024;
while i < len {
let sz = std::cmp::min(i + batch_len, len) - i;
let mut buf = vec![0u8; sz as usize];
reader.read_exact(&mut buf)?;
result.extend_from_slice(&buf);
i += sz;
}
String::from_utf8(result)
.map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err.to_string()))
}
} Got the following results for
|
Very cool, we should do the same for |
Latest:
|
Well, I think I incorrectly implemented the deserialization for fixed size items, need more work on it |
Added a few extra tests
|
I think |
Latest metrics with optimized deserialization from Borsh, see near/borsh#58 Input Highlights:Cost of Borsh input of (s: String) where s="" is 9,080,640,736 All
|
Optimizing strings/vec<u8> reads using custom implementation for `Vec<u8>` with a bit of unsafe code, but without UB. Switching deserialization to use `&mut &[u8]` instead of `BufRead`. It allows us to switch to `BorshError` instead of `std::io::Error` in the future to go with `no_std`. # Test plan - Added unit tests for `String` and `Vec<T>` - Verified gas cost by linking borsh directly to gas fee meter. See near/nearcore#1829 - Re-running benchmarks
Added an example to run NEAR Runtime standalone runner to compare gas fess between different serialization methods and computing average gas usage per byte/number/element Issue: near/nearcore#1829
We made some important gas measurements. The rest is not crucial for the Mainnet launch. Moving to the Ice Box. |
Optimizing strings/vec<u8> reads using custom implementation for `Vec<u8>` with a bit of unsafe code, but without UB. Switching deserialization to use `&mut &[u8]` instead of `BufRead`. It allows us to switch to `BorshError` instead of `std::io::Error` in the future to go with `no_std`. # Test plan - Added unit tests for `String` and `Vec<T>` - Verified gas cost by linking borsh directly to gas fee meter. See near/nearcore#1829 - Re-running benchmarks
Optimizing strings/vec<u8> reads using custom implementation for `Vec<u8>` with a bit of unsafe code, but without UB. Switching deserialization to use `&mut &[u8]` instead of `BufRead`. It allows us to switch to `BorshError` instead of `std::io::Error` in the future to go with `no_std`. # Test plan - Added unit tests for `String` and `Vec<T>` - Verified gas cost by linking borsh directly to gas fee meter. See near/nearcore#1829 - Re-running benchmarks
This issue has been automatically marked as stale because it has not had recent activity in the last 2 months. |
@evgenykuzyakov are there still any action items here? if not let's close the issue |
This issue has been automatically marked as stale because it has not had recent activity in the last 2 months. |
Duplicate of #2501 |
Added an example to run NEAR Runtime standalone runner to compare gas fess between different serialization methods and computing average gas usage per byte/number/element Issue: near/nearcore#1829
We need to have examples of typical blockchain contracts and we need to study these contracts: how much gas use, how much TPS they allow, how many cross-contract hops do they take.
The text was updated successfully, but these errors were encountered: