GithubHelp home page GithubHelp logo

Add BorshSize trait about borsh-rs HOT 3 CLOSED

near avatar near commented on May 23, 2024 1
Add BorshSize trait

from borsh-rs.

Comments (3)

matklad avatar matklad commented on May 23, 2024 1

80% solution:

pub fn borsh_len(value: &impl BorshSerialize) -> Result<usize> {
    struct Writer {
        len: usize,
    }
    impl Write for Writer {
        #[inline]
        fn write(&mut self, buf: &[u8]) -> Result<usize> {
            self.len += buf.len();
            Ok(buf.len())
        }
        #[inline]
        fn flush(&mut self) -> Result<()> {
            Ok(())
        }
    }
    let mut w = Writer { len: 0 };
    value.serialize(&mut w)?;
    Ok(w.len)
}

This won't do exactly what we want for types that use extra heap-allocated buffers for serilization, but my gut feeling is that that's rare.

EDIT: didnt' resist the temptation to look at the asm, looks right for simple cases:

15:22:23|~/projects/borsh-rs|master⚡✚*
λ git diff --cached
diff --git a/borsh/examples/len.rs b/borsh/examples/len.rs
new file mode 100644
index 00000000..69b84a0c
--- /dev/null
+++ b/borsh/examples/len.rs
@@ -0,0 +1,17 @@
+#[derive(borsh::BorshSerialize)]
+pub struct Foo {
+    x: u8,
+    y: u32
+}
+
+#[no_mangle]
+#[inline(never)]
+pub fn size_of_foo(foo: &Foo) -> usize {
+    borsh::len(foo).unwrap_or_default()
+}
+
+fn main() {
+    let foo = Foo { x: 62, y: 92 };
+    let res = size_of_foo(&foo);
+    eprintln!("{}", res);
+}
diff --git a/borsh/src/lib.rs b/borsh/src/lib.rs
index 51c81919..55088283 100644
--- a/borsh/src/lib.rs
+++ b/borsh/src/lib.rs
@@ -45,3 +45,23 @@ pub mod maybestd {
         pub use hashbrown::hash_map::Entry;
     }
 }
+
+pub fn len(value: &impl BorshSerialize) -> std::io::Result<usize> {
+    struct Writer {
+        len: usize,
+    }
+    impl std::io::Write for Writer {
+        #[inline]
+        fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
+            self.len += buf.len();
+            Ok(buf.len())
+        }
+        #[inline]
+        fn flush(&mut self) -> std::io::Result<()> {
+            Ok(())
+        }
+    }
+    let mut w = Writer { len: 0 };
+    value.serialize(&mut w)?;
+    Ok(w.len)
+}

15:22:28|~/projects/borsh-rs|master⚡✚*
λ cargo build --example len --release -q

15:22:41|~/projects/borsh-rs|master⚡✚*
λ dis ./target/release/examples/len size_of_foo
Dump of assembler code for function size_of_foo:
   0x0000000000011b70 <+0>:	mov    eax,0x5
   0x0000000000011b75 <+5>:	ret    
End of assembler dump.

from borsh-rs.

matklad avatar matklad commented on May 23, 2024 1

And output for slightly more intersting

#[derive(borsh::BorshSerialize)]
pub struct Foo {
    x: u8,
    y: u32,
    zs: Vec<u32>,
}
Dump of assembler code for function size_of_foo:
   0x0000000000011be0 <+0>:	mov    rax,QWORD PTR [rdi+0x10]
   0x0000000000011be4 <+4>:	mov    rcx,rax
   0x0000000000011be7 <+7>:	shr    rcx,0x20
   0x0000000000011beb <+11>:	test   rax,rax
   0x0000000000011bee <+14>:	lea    rax,[rax*4+0x9]
   0x0000000000011bf6 <+22>:	mov    edx,0x9
   0x0000000000011bfb <+27>:	cmovne rdx,rax
   0x0000000000011bff <+31>:	xor    eax,eax
   0x0000000000011c01 <+33>:	test   rcx,rcx
   0x0000000000011c04 <+36>:	cmove  rax,rdx
   0x0000000000011c08 <+40>:	ret    
End of assembler dump.

from borsh-rs.

nearmax avatar nearmax commented on May 23, 2024

What a trick :D

from borsh-rs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.