[Python-checkins] CVS: python/dist/src/Objects stringobject.c,2.107,2.108

Tim Peters tim_one@users.sourceforge.net
Tue, 08 May 2001 15:33:53 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv979/python/dist/src/Objects

Modified Files:
	stringobject.c 
Log Message:
Intern 1-character strings as soon as they're created.  As-is, they aren't
interned when created, so the cached versions generally aren't ever
interned.  With the patch, the
		Py_INCREF(t);
		*p = t;
		Py_DECREF(s);
		return;
indirection block in PyString_InternInPlace() is never executed during a
full run of the test suite, but was executed very many times before.  So
I'm trading more work when creating one-character strings for doing less
work later.  Note that the "more work" here can happen at most 256 times
per program run, so it's trivial.  The same reasoning accounts for the
patch's simplification of string_item (the new version can call
PyString_FromStringAndSize() no more than 256 times per run, so there's
no point to inlining that stuff -- if we were serious about saving time
here, we'd pre-initialize the characters vector so that no runtime testing
at all was needed!).


Index: stringobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v
retrieving revision 2.107
retrieving revision 2.108
diff -C2 -r2.107 -r2.108
*** stringobject.c	2001/05/05 05:36:48	2.107
--- stringobject.c	2001/05/08 22:33:50	2.108
***************
*** 37,41 ****
  PyString_FromStringAndSize(const char *str, int size)
  {
! 	register PyStringObject *op;
  #ifndef DONT_SHARE_SHORT_STRINGS
  	if (size == 0 && (op = nullstring) != NULL) {
--- 37,41 ----
  PyString_FromStringAndSize(const char *str, int size)
  {
! 	PyStringObject *op;
  #ifndef DONT_SHARE_SHORT_STRINGS
  	if (size == 0 && (op = nullstring) != NULL) {
***************
*** 74,80 ****
--- 74,82 ----
  #ifndef DONT_SHARE_SHORT_STRINGS
  	if (size == 0) {
+ 		PyString_InternInPlace(&(PyObject *)op);
  		nullstring = op;
  		Py_INCREF(op);
  	} else if (size == 1 && str != NULL) {
+ 		PyString_InternInPlace(&(PyObject *)op);
  		characters[*str & UCHAR_MAX] = op;
  		Py_INCREF(op);
***************
*** 88,92 ****
  {
  	register size_t size = strlen(str);
! 	register PyStringObject *op;
  	if (size > INT_MAX) {
  		PyErr_SetString(PyExc_OverflowError,
--- 90,94 ----
  {
  	register size_t size = strlen(str);
! 	PyStringObject *op;
  	if (size > INT_MAX) {
  		PyErr_SetString(PyExc_OverflowError,
***************
*** 126,132 ****
--- 128,136 ----
  #ifndef DONT_SHARE_SHORT_STRINGS
  	if (size == 0) {
+ 		PyString_InternInPlace(&(PyObject *)op);
  		nullstring = op;
  		Py_INCREF(op);
  	} else if (size == 1) {
+ 		PyString_InternInPlace(&(PyObject *)op);
  		characters[*str & UCHAR_MAX] = op;
  		Py_INCREF(op);
***************
*** 552,573 ****
  	int c;
  	PyObject *v;
  	if (i < 0 || i >= a->ob_size) {
  		PyErr_SetString(PyExc_IndexError, "string index out of range");
  		return NULL;
  	}
! 	c = a->ob_sval[i] & UCHAR_MAX;
  	v = (PyObject *) characters[c];
! #ifdef COUNT_ALLOCS
! 	if (v != NULL)
! 		one_strings++;
! #endif
! 	if (v == NULL) {
! 		v = PyString_FromStringAndSize((char *)NULL, 1);
! 		if (v == NULL)
! 			return NULL;
! 		characters[c] = (PyStringObject *) v;
! 		((PyStringObject *)v)->ob_sval[0] = c;
! 	}
! 	Py_INCREF(v);
  	return v;
  }
--- 556,570 ----
  	int c;
  	PyObject *v;
+ 	char *pchar;
  	if (i < 0 || i >= a->ob_size) {
  		PyErr_SetString(PyExc_IndexError, "string index out of range");
  		return NULL;
  	}
! 	pchar = a->ob_sval + i;
! 	c = *pchar & UCHAR_MAX;
  	v = (PyObject *) characters[c];
! 	if (v == NULL)
! 		v = PyString_FromStringAndSize(pchar, 1);
! 	Py_XINCREF(v);
  	return v;
  }