shared: add NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 define

When we have a buffer that we want to grow exponentially with
nm_utils_get_next_realloc_size(), then there are certain buffer
sizes that are better suited.

For example, if you have an empty NMStrBuf (len == 0), and you
want to allocate roughly one kilobyte, then 1024 is a bad choice,
because nm_utils_get_next_realloc_size() will give you 2024 bytes.

NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 might be better in this case.
This commit is contained in:
Thomas Haller
2020-04-06 10:39:05 +02:00
parent aede8fa554
commit d1c2572e11
2 changed files with 25 additions and 0 deletions

View File

@@ -1835,6 +1835,26 @@ nm_utils_strdup_reset (char **dst, const char *src)
/*****************************************************************************/ /*****************************************************************************/
/* nm_utils_get_next_realloc_size() is used to grow buffers exponentially, when
* the final size is unknown. As such, it has borders for which it allocates
* certain buffer sizes.
*
* The use of these defines is to get favorable allocation sequences.
* For example, nm_str_buf_init() asks for an initial allocation size. Note that
* it reserves the exactly requested amount, under the assumption that the
* user may know how many bytes will be required. However, often the caller
* doesn't know in advance, and NMStrBuf grows exponentially by calling
* nm_utils_get_next_realloc_size().
* Imagine you call nm_str_buf_init() with an initial buffer size 100, and you
* add one character at a time. Then the first reallocation will increase the
* buffer size only from 100 to 104.
* If you however start with an initial buffer size of 104, then the next reallocation
* via nm_utils_get_next_realloc_size() gives you 232, and so on. By using
* these sizes, it results in fewer reallocations, if you anyway don't now the exact
* size in advance. */
#define NM_UTILS_GET_NEXT_REALLOC_SIZE_104 ((gsize) 104)
#define NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 ((gsize) 1000)
gsize nm_utils_get_next_realloc_size (gboolean true_realloc, gsize requested); gsize nm_utils_get_next_realloc_size (gboolean true_realloc, gsize requested);
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -635,9 +635,14 @@ test_nm_utils_get_next_realloc_size (void)
{ G_MAXSIZE - 24u, G_MAXSIZE, G_MAXSIZE }, { G_MAXSIZE - 24u, G_MAXSIZE, G_MAXSIZE },
{ G_MAXSIZE - 1u, G_MAXSIZE, G_MAXSIZE }, { G_MAXSIZE - 1u, G_MAXSIZE, G_MAXSIZE },
{ G_MAXSIZE, G_MAXSIZE, G_MAXSIZE }, { G_MAXSIZE, G_MAXSIZE, G_MAXSIZE },
{ NM_UTILS_GET_NEXT_REALLOC_SIZE_104, NM_UTILS_GET_NEXT_REALLOC_SIZE_104, NM_UTILS_GET_NEXT_REALLOC_SIZE_104 },
{ NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 },
}; };
guint i; guint i;
G_STATIC_ASSERT_EXPR (NM_UTILS_GET_NEXT_REALLOC_SIZE_104 == 104u);
G_STATIC_ASSERT_EXPR (NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 == 1000u);
for (i = 0; i < G_N_ELEMENTS (test_data) + 5000u; i++) { for (i = 0; i < G_N_ELEMENTS (test_data) + 5000u; i++) {
gsize requested0; gsize requested0;