>>>>> "Fred" == Fred Lindberg <[EMAIL PROTECTED]> writes:

Fred> Monty:
Fred> Here is fmt_ulong() from Dan Bernstein's library:

Fred> #define FMT_ULONG 40 /* enough space to hold 2^128 - 1 in decimal, plus
Fred> \0 */

Fred> unsigned int fmt_ulong(s,u) register char *s; register unsigned long u;
Fred> {
Fred>   register unsigned int len; register unsigned long q;
Fred>   len = 1; q = u;
Fred>   while (q > 9) { ++len; q /= 10; }
Fred>   if (s) {
Fred>     s += len;
Fred>     do { *--s = '0' + (u % 10); u /= 10; } while(u); /* handles u == 0
Fred> */
Fred>   }
Fred>   return len;
Fred> }

Fred> It makes the number as short as possible, but by fixing len and
Fred> skipping, it's easy to convert to a function that fills YYYY-MM-DD
Fred> HH:MM:DD or whatever is needed and circumvent sprintf() entirely. You
Fred> are now using a probably quite general routine if sprintf() to fill the
Fred> multiple %02d fields, each of which has an overhead in the same order
Fred> of magnitude as the entire conversion.

Hi!

I thought about this a little and came up with the following:

-------
String *Field_datetime::val_str(String *val_buffer,String *val_ptr)
{
  val_buffer->alloc(field_length);
  val_buffer->length(field_length);
  ulonglong tmp;
  ulong part1,part2;
  char *pos;
  int part3;

  longlongget(tmp,ptr);

  /*
    Avoid problem with slow longlong aritmetic and sprintf
  */

  part1=(ulong) (tmp/LL(1000000));
  part2=(ulong) (tmp - (ulonglong) part1*LL(1000000));

  pos=(char*) val_buffer->ptr()+19;
  *pos--=0;
  *pos--='0'+part2%10; part2/=10;
  *pos--='0'+part2%10; part3= (int) (part2 / 10);
  *pos--=':';
  *pos--='0'+part3%10; part3/=10;
  *pos--='0'+part3%10; part3/=10;
  *pos--=':';
  *pos--='0'+part3%10; part3/=10;
  *pos--='0'+part3;
  *pos--=' ';
  *pos--='0'+part1%10; part1/=10;
  *pos--='0'+part1%10; part1/=10;
  *pos--='-';
  *pos--='0'+part1%10; part1/=10;
  *pos--='0'+part1%10; part3= (int) (part1/10);
  *pos--='-';
  *pos--='0'+part3%10; part3/=10;
  *pos--='0'+part3%10; part3/=10;
  *pos--='0'+part3%10; part3/=10;
  *pos='0'+part3;
  return val_buffer;
}
--------

This is about 5 times faster than the code in MySQL 3.22.15
(This doesn't of course solve the general itoa() problem with
longlong for which we still need a solution, but makes datetime
handling much better)

Regards,
Monty
-----------------------------------------------------------
Send a mail to [EMAIL PROTECTED] with
unsubscribe mysql [EMAIL PROTECTED]
in the body of the message to unsubscribe from this list.

Reply via email to