g_strjoinv() is very slow


 I've recently discovered that the g_strjoinv() function (and this is also
true for g_strjoin()) is very slow when it comes to join many long strings.
After some investigation, it seems that it is due to the strcat() function.

So I've written a new version of g_strjoin() without strcat() but with
memcpy() and strlen() instead. And I'm very surprised with the results.
It looks like my function is about 100 times fater than g_strjoinv().

  I've attached to this mail a sample program to test this new function.

  Please have a look at it. I can make a patch against glib-1.2.8 or against
current CVS HEAD.



David Odin bigfoot com

#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <glib.h>

g_strjoinv2 (const gchar  *separator,
             gchar       **str_array)
  gchar *string;
  gchar *ptr;

  g_return_val_if_fail (str_array != NULL, NULL);

  if (separator == NULL)
    separator = "";

  if (*str_array)
    guint i, len;
    guint separator_len;

    separator_len = strlen (separator);
    len = 1 + strlen (str_array[0]);
    for(i = 1; str_array[i] != NULL; i++)
      len += strlen(str_array[i]);
    len += separator_len*i;

    string = g_new (gchar, len);
    *string = 0;
    strcat (string, *str_array);
    ptr = string + strlen (*str_array);
    for (i = 1; str_array[i] != NULL; i++)
      memcpy (ptr, separator, separator_len);
      memcpy (ptr + separator_len, str_array[i], strlen (str_array[i]));
      ptr += separator_len + strlen (str_array[i]);
    string = g_strdup ("");

  return string;

int main(int argc, char *argv[])
  guint i;
  gchar **array;
  time_t time1, time2;

  array = g_malloc(201*sizeof(gchar *));
  for (i=0 ; i<200 ; i++)
    guint length, j;

    length = rand()%256;
    array[i] = g_malloc((length+1)*sizeof(gchar));
    for (j=0 ; j<length ; j++)
      array[i][j] = 'A' + (rand()%26);
    array[i][j] = 0;
  array[i] = NULL;
  time1 = time(NULL);
  for (i=0 ; i<3000 ; i++)
    g_free(g_strjoinv("\n", array));
  time2 = time(NULL);
  g_print("g_strjoinv: %ld\n", time2-time1);
  time1 = time(NULL);
  for (i=0 ; i<3000 ; i++)
    g_free(g_strjoinv2("\n", array));
  time2 = time(NULL);
  g_print("g_strjoinv2: %ld\n", time2-time1);
  return 0;

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]