Skip to content
Snippets Groups Projects
  • Stepan Koltsov's avatar
    7110d57b
    BytesMut::reserve should not overallocate (#117) · 7110d57b
    Stepan Koltsov authored
    Round up to power of 2 is not necessary, because `reserve` already
    doubles previous capacity in
    
    ```
    	new_cap = cmp::max(
    		cmp::max(v.capacity() << 1, new_cap),
    		original_capacity);
    ```
    
    which makes `reserve` calls constant in average. Avoiding rounding
    up prevents `reserve` from wasting space when caller knows exactly
    what space they need.
    
    Patch adds three tests which would fail before this test. The most
    important is this:
    
    ```
    #[test]
    fn reserve_in_arc_unique_does_not_overallocate() {
        let mut bytes = BytesMut::with_capacity(1000);
        bytes.take();
    
        // now bytes is Arc and refcount == 1
    
        assert_eq!(1000, bytes.capacity());
        bytes.reserve(2001);
        assert_eq!(2001, bytes.capacity());
    }
    ```
    
    It asserts that when user requests more than double of current
    capacity, exactly the requested amount of memory is allocated and
    is not wasted to next power of two.
    7110d57b
    History
    BytesMut::reserve should not overallocate (#117)
    Stepan Koltsov authored
    Round up to power of 2 is not necessary, because `reserve` already
    doubles previous capacity in
    
    ```
    	new_cap = cmp::max(
    		cmp::max(v.capacity() << 1, new_cap),
    		original_capacity);
    ```
    
    which makes `reserve` calls constant in average. Avoiding rounding
    up prevents `reserve` from wasting space when caller knows exactly
    what space they need.
    
    Patch adds three tests which would fail before this test. The most
    important is this:
    
    ```
    #[test]
    fn reserve_in_arc_unique_does_not_overallocate() {
        let mut bytes = BytesMut::with_capacity(1000);
        bytes.take();
    
        // now bytes is Arc and refcount == 1
    
        assert_eq!(1000, bytes.capacity());
        bytes.reserve(2001);
        assert_eq!(2001, bytes.capacity());
    }
    ```
    
    It asserts that when user requests more than double of current
    capacity, exactly the requested amount of memory is allocated and
    is not wasted to next power of two.