Index: GooString.cc =================================================================== --- GooString.cc (revision 36) +++ GooString.cc (working copy) @@ -21,7 +21,56 @@ #include "gtypes.h" #include "GooString.h" -static inline int size(int len) { +#define HIST_SIZE 12048 + +#define SIZE 0 +#define COUNT 1 +static int gStrSizeHist[HIST_SIZE][2] = {0}; +static int gHistEntries = 0; + +extern "C" { +#ifdef _WIN32 + void win32_dbg_out(const char *format, ...); + #define DBG_OUT win32_dbg_out + #else + #define DBG_OUT printf +#endif +} + +/* slow but works */ +static void histAdd(int size) +{ +#ifdef DO_HIST + int i; + + for (i = 0; i < gHistEntries; i++) { + if (gStrSizeHist[i][SIZE] == size) { + gStrSizeHist[i][COUNT] += 1; + return; + } + } + if (gHistEntries >= (HIST_SIZE - 1)) { + DBG_OUT("gHistEntries (%d) reached max HIST_SIZE (%d)\n", gHistEntries, (int)HIST_SIZE); + return; + } + gStrSizeHist[i][SIZE] = size; + gStrSizeHist[i][COUNT] = 1; + ++gHistEntries; +#endif +} + +void histDump(void) +{ +#ifdef DO_HIST + DBG_OUT("STRING HISTOGRAM DUMP START\n"); + for (int i = 0; i < gHistEntries; i++) { + DBG_OUT("%d,%d\n", gStrSizeHist[i][SIZE], gStrSizeHist[i][COUNT]); + } + DBG_OUT("STRING HISTOGRAM DUMP END\n"); +#endif +} + +static inline int rounded_size(int len) { int delta; delta = len < 256 ? 7 : 255; @@ -32,16 +81,35 @@ char *s1; if (!s) { - s = new char[size(length1)]; - } else if (size(length1) != size(length)) { - s1 = new char[size(length1)]; +#ifdef FAST_GOO_STRING + if (rounded_size(length1) <= GSTR_STATIC_SIZE) + s = sStatic; + else + s = new char[rounded_size(length1)]; +#else + s = new char[rounded_size(length1)]; +#endif + } else if (rounded_size(length1) != rounded_size(length)) { +#ifdef FAST_GOO_STRING + if (rounded_size(length1) <= GSTR_STATIC_SIZE) + s1 = sStatic; + else + s1 = new char[rounded_size(length1)]; +#else + s1 = new char[rounded_size(length1)]; +#endif if (length1 < length) { memcpy(s1, s, length1); s1[length1] = '\0'; } else { memcpy(s1, s, length + 1); } +#ifdef FAST_GOO_STRING + if (s != sStatic) + delete[] s; +#else delete[] s; +#endif s = s1; } } @@ -117,7 +185,9 @@ } GooString::~GooString() { - delete[] s; + histAdd(rounded_size(length)); + if (s != sStatic) + delete[] s; } GooString *GooString::clear() { Index: GooString.h =================================================================== --- GooString.h (revision 36) +++ GooString.h (working copy) @@ -17,6 +17,14 @@ #include "gtypes.h" +#define FAST_GOO_STRING 1 +//#define DO_HIST 1 +void histDump(void); + +/* I think this could just as well be 24 so that sizeof(GooString) is 32, + because it'll probably be anyway. */ +#define GSTR_STATIC_SIZE 16 + class GooString { public: @@ -90,6 +98,9 @@ private: +#ifdef FAST_GOO_STRING + char sStatic[GSTR_STATIC_SIZE]; +#endif int length; char *s;