Branch: Tag:

2000-07-27

2000-07-27 17:47:29 by Andreas Lange <andreas@lange.cx>

upper_case/lower_case up to 25% faster for 8bit wide strings

Rev: bin/make_ci.pike:1.5
Rev: src/builtin_functions.c:1.292
Rev: src/dummy_ci.h:1.4

5:   \*/   /**/   #include "global.h" - RCSID("$Id: builtin_functions.c,v 1.291 2000/07/19 16:48:51 lange Exp $"); + RCSID("$Id: builtin_functions.c,v 1.292 2000/07/27 17:47:29 lange Exp $");   #include "interpret.h"   #include "svalue.h"   #include "pike_macros.h"
186:    return(cache = (struct case_info *)case_info + lo);   }    + static struct case_info *find_ci_shift0(int c) + { +  static struct case_info *cache = NULL; +  struct case_info *ci = cache; +  int lo = 0; +  int hi = CASE_INFO_SHIFT0_HIGH; +  +  if ((c < 0) || (c > 0xffff)) +  return NULL; +  +  if ((ci) && (ci[0].low <= c) && (ci[1].low > c)) { +  return ci; +  } +  +  while (lo != hi-1) { +  int mid = (lo + hi)>>1; +  if (case_info[mid].low < c) { +  lo = mid; +  } else if (case_info[mid].low == c) { +  lo = mid; +  break; +  } else { +  hi = mid; +  } +  } +  return(cache = (struct case_info *)case_info + lo); + } +    #define DO_LOWER_CASE(C) do {\    int c = C; \    struct case_info *ci = find_ci(c); \
200:    } \    } while(0)    + #define DO_LOWER_CASE_SHIFT0(C) do {\ +  int c = C; \ +  struct case_info *ci = find_ci_shift0(c); \ +  if (ci) { \ +  switch(ci->mode) { \ +  case CIM_NONE: case CIM_LOWERDELTA: break; \ +  case CIM_UPPERDELTA: C = c + ci->data; break; \ +  case CIM_CASEBIT: C = c | ci->data; break; \ +  case CIM_CASEBITOFF: C = ((c - ci->data) | ci->data) + ci->data; break; \ +  default: fatal("lower_case(): Unknown case_info mode: %d\n", ci->mode); \ +  } \ +  } \ +  } while(0) +    #define DO_UPPER_CASE(C) do {\    int c = C; \    struct case_info *ci = find_ci(c); \
214:    } \    } while(0)    + #define DO_UPPER_CASE_SHIFT0(C) do {\ +  int c = C; \ +  struct case_info *ci = find_ci_shift0(c); \ +  if (ci) { \ +  switch(ci->mode) { \ +  case CIM_NONE: case CIM_UPPERDELTA: break; \ +  case CIM_LOWERDELTA: C = c - ci->data; break; \ +  case CIM_CASEBIT: C = c & ~ci->data; break; \ +  case CIM_CASEBITOFF: C = ((c - ci->data)& ~ci->data) + ci->data; break; \ +  default: fatal("lower_case(): Unknown case_info mode: %d\n", ci->mode); \ +  } \ +  } \ +  } while(0) +    void f_lower_case(INT32 args)   {    INT32 i;
231:    p_wchar0 *str = STR0(ret);       while(i--) { -  DO_LOWER_CASE(str[i]); +  DO_LOWER_CASE_SHIFT0(str[i]);    }    } else if (orig->size_shift == 1) {    p_wchar1 *str = STR1(ret);
271:       while(i--) {    if(str[i]!=0xff && str[i]!=0xb5) { -  DO_UPPER_CASE(str[i]); +  DO_UPPER_CASE_SHIFT0(str[i]);    } else {    widen = 1;    }