Extra Fast Growing (GNU libiberty)

#### 2.3.1.7 Extra Fast Growing Objects ¶

The usual macros for growing objects incur overhead for checking whether there is room for the new growth in the current chunk. If you are frequently constructing objects in small steps of growth, this overhead can be significant.

You can reduce the overhead by using special “fast growth” macros that grow the object without checking. In order to have a robust program, you must do the checking yourself. If you do this checking in the simplest way each time you are about to add data to the object, you have not saved anything, because that is what the ordinary growth macros do. But if you can arrange to check less often, or check more efficiently, then you make the program faster.

`obstack_room` returns the amount of room available in the current chunk.

Function: `size_t` obstack_room `(struct obstack *obstack-ptr)` ¶

  This returns the number of bytes that can be added safely to the current growing object (or to an object about to be started) in obstack obstack using the fast growth macros.

While you know there is room, you can use these fast growth macros for adding data to a growing object:

Function: `void` obstack_1grow_fast `(struct obstack *obstack-ptr, char c)` ¶

  `obstack_1grow_fast` adds one byte containing the character c to the growing object in obstack obstack-ptr.

Function: `void` obstack_ptr_grow_fast `(struct obstack *obstack-ptr, void *data)` ¶

  `obstack_ptr_grow_fast` adds `sizeof (void *)` bytes containing the value of data to the growing object in obstack obstack-ptr.

Function: `void` obstack_int_grow_fast `(struct obstack *obstack-ptr, int data)` ¶

  `obstack_int_grow_fast` adds `sizeof (int)` bytes containing the value of data to the growing object in obstack obstack-ptr.

Function: `void` obstack_blank_fast `(struct obstack *obstack-ptr, size_t size)` ¶

  `obstack_blank_fast` adds size bytes to the growing object in obstack obstack-ptr without initializing them.

When you check for space using `obstack_room` and there is not enough room for what you want to add, the fast growth macros are not safe. In this case, simply use the corresponding ordinary growth macro instead. Very soon this will copy the object to a new chunk; then there will be lots of room available again.

So, each time you use an ordinary growth macro, check afterward for sufficient space using `obstack_room`. Once the object is copied to a new chunk, there will be plenty of space again, so the program will start using the fast growth macros again.

Here is an example:

    void
    add_string (struct obstack *obstack, const char *ptr, size_t len)
    {
      while (len > 0)
        {
          size_t room = obstack_room (obstack);
          if (room == 0)
            {
              /* Not enough room.  Add one character slowly,
                 which may copy to a new chunk and make room.  */
              obstack_1grow (obstack, *ptr++);
              len--;
            }
          else
            {
              if (room > len)
                room = len;
              /* Add fast as much as we have room for. */
              len -= room;
              while (room-- > 0)
                obstack_1grow_fast (obstack, *ptr++);
            }
        }
    }

You can use `obstack_blank_fast` with a “negative” size argument to make the current object smaller. Just don’t try to shrink it beyond zero length—there’s no telling what will happen if you do that. Earlier versions of obstacks allowed you to use `obstack_blank` to shrink objects. This will no longer work.