T
direkt festgelegt bin ich nicht, jedoch sind alle sachen die zusätzlich noch gemacht werden müssen mit dieser logzeile schon jetzt auf std::string aufgebaut bzw. es wird jetzt schon das ergebnis von vsnprinft+fixer buffer in einen std::string kopiert.
hab mir nun, so wie von dir empfohlen, den sourcecode von vasprintf rausgesucht
ich hoffe, dass ist der richtige
http://www.google.com/codesearch/p?hl=de#qoCVjtE_vOw/gcc/trunk/gcc-3.4.6/libiberty/vasprintf.c
vasprintf berechnet zuerst den größten möglichen speicher und reserviert diesen.beim return wird die eigentlich verwendete speicheranzahl zurückgegeben.
int int_vasprintf (char **result, const char* format, va_list args)
{
const char *p = format;
/* Add one to make sure that it is never zero, which might cause malloc
to return NULL. */
int total_width = strlen (format) + 1;
va_list ap;
va_copy (ap, args);
while (*p != '\0')
{
if (*p++ == '%')
{
while (strchr ("-+ #0", *p))
++p;
if (*p == '*')
{
++p;
total_width += abs (va_arg (ap, int));
}
else
total_width += strtoul (p, (char **) &p, 10);
if (*p == '.')
{
++p;
if (*p == '*')
{
++p;
total_width += abs (va_arg (ap, int));
}
else
total_width += strtoul (p, (char **) &p, 10);
}
while (strchr ("hlL", *p))
++p;
/* Should be big enough for any format specifier except %s and floats. */
total_width += 30;
switch (*p)
{
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X':
case 'c':
(void) va_arg (ap, int);
break;
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
(void) va_arg (ap, double);
/* Since an ieee double can have an exponent of 307, we'll
make the buffer wide enough to cover the gross case. */
total_width += 307;
break;
case 's':
total_width += strlen (va_arg (ap, char *));
break;
case 'p':
case 'n':
(void) va_arg (ap, char *);
break;
}
p++;
}
}
va_end (ap);
*result = (char *) malloc (total_width);
if(*result != NULL)
return vsprintf (*result, format, args);
else
return -1;
}
interessant ist, wenn ich eben statt
*result = (char *) malloc (total_width);
if(*result != NULL)
return vsprintf (*result, format, args);
else
return -1;
meine std::string ausführung mache:
result.resize(total_width);
if (result.size() > 0)
return vsprintf (&result[0], format, args);
else
return -1;
die std::string variante langsamer ist als eben int_vasprintf + str.append(pstr, n);
ist das speicherreservieren beim std::string um so viel langsamer als ein malloc?
bei meinem test ist somit ein malloc von 937 + std::string.append von der länge von 515 schneller wie das resize von 937