mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	Give meaning to the oparg for BUILD_MAP: estimated size of the dictionary.
Allows dictionaries to be pre-sized (upto 255 elements) saving time lost to re-sizes with their attendant mallocs and re-insertions. Has zero effect on small dictionaries (5 elements or fewer), a slight benefit for dicts upto 22 elements (because they had to resize once anyway), and more benefit for dicts upto 255 elements (saving multiple resizes during the build-up and reducing the number of collisions on the first insertions). Beyond 255 elements, there is no addional benefit.
This commit is contained in:
		
							parent
							
								
									3c887b2802
								
							
						
					
					
						commit
						fd7ed407d7
					
				
					 6 changed files with 26 additions and 6 deletions
				
			
		|  | @ -110,6 +110,7 @@ PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp); | ||||||
| PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp); | PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp); | ||||||
| PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key); | PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key); | ||||||
| PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, long hash); | PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, long hash); | ||||||
|  | PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused); | ||||||
| 
 | 
 | ||||||
| /* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */ | /* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */ | ||||||
| PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other); | PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other); | ||||||
|  |  | ||||||
|  | @ -139,7 +139,7 @@ def jabs_op(name, op): | ||||||
| name_op('LOAD_NAME', 101)       # Index in name list | name_op('LOAD_NAME', 101)       # Index in name list | ||||||
| def_op('BUILD_TUPLE', 102)      # Number of tuple items | def_op('BUILD_TUPLE', 102)      # Number of tuple items | ||||||
| def_op('BUILD_LIST', 103)       # Number of list items | def_op('BUILD_LIST', 103)       # Number of list items | ||||||
| def_op('BUILD_MAP', 104)        # Always zero for now | def_op('BUILD_MAP', 104)        # Number of dict entries (upto 255) | ||||||
| name_op('LOAD_ATTR', 105)       # Index in name list | name_op('LOAD_ATTR', 105)       # Index in name list | ||||||
| def_op('COMPARE_OP', 106)       # Comparison operator | def_op('COMPARE_OP', 106)       # Comparison operator | ||||||
| hascompare.append(106) | hascompare.append(106) | ||||||
|  |  | ||||||
|  | @ -12,6 +12,10 @@ What's New in Python 2.6 alpha 1? | ||||||
| Core and builtins | Core and builtins | ||||||
| ----------------- | ----------------- | ||||||
| 
 | 
 | ||||||
|  | - Compiler now generates simpler and faster code for dictionary literals. | ||||||
|  |   The oparg for BUILD_MAP now indicates an estimated dictionary size. | ||||||
|  |   There is a new opcode, STORE_MAP, for adding entries to the dictionary. | ||||||
|  | 
 | ||||||
| - Issue #1638: %zd configure test fails on Linux | - Issue #1638: %zd configure test fails on Linux | ||||||
| 
 | 
 | ||||||
| - Issue #1620: New property decorator syntax was modifying the decorator | - Issue #1620: New property decorator syntax was modifying the decorator | ||||||
|  |  | ||||||
|  | @ -549,6 +549,23 @@ dictresize(PyDictObject *mp, Py_ssize_t minused) | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* Create a new dictionary pre-sized to hold an estimated number of elements.
 | ||||||
|  |    Underestimates are okay because the dictionary will resize as necessary. | ||||||
|  |    Overestimates just mean the dictionary will be more sparse than usual. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | PyObject * | ||||||
|  | _PyDict_NewPresized(Py_ssize_t minused) | ||||||
|  | { | ||||||
|  | 	PyObject *op = PyDict_New(); | ||||||
|  | 
 | ||||||
|  | 	if (minused>5 && op != NULL && dictresize((PyDictObject *)op, minused) == -1) { | ||||||
|  | 		Py_DECREF(op); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 	return op; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* Note that, for historical reasons, PyDict_GetItem() suppresses all errors
 | /* Note that, for historical reasons, PyDict_GetItem() suppresses all errors
 | ||||||
|  * that may occur (originally dicts supported only string keys, and exceptions |  * that may occur (originally dicts supported only string keys, and exceptions | ||||||
|  * weren't possible).  So, while the original intent was that a NULL return |  * weren't possible).  So, while the original intent was that a NULL return | ||||||
|  |  | ||||||
|  | @ -1997,7 +1997,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
| 		case BUILD_MAP: | 		case BUILD_MAP: | ||||||
| 			x = PyDict_New(); | 			x = _PyDict_NewPresized((Py_ssize_t)oparg); | ||||||
| 			PUSH(x); | 			PUSH(x); | ||||||
| 			if (x != NULL) continue; | 			if (x != NULL) continue; | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
|  | @ -2922,11 +2922,9 @@ compiler_visit_expr(struct compiler *c, expr_ty e) | ||||||
| 	case IfExp_kind: | 	case IfExp_kind: | ||||||
| 		return compiler_ifexp(c, e); | 		return compiler_ifexp(c, e); | ||||||
| 	case Dict_kind: | 	case Dict_kind: | ||||||
| 		/* XXX get rid of arg? */ |  | ||||||
| 		ADDOP_I(c, BUILD_MAP, 0); |  | ||||||
| 		n = asdl_seq_LEN(e->v.Dict.values); | 		n = asdl_seq_LEN(e->v.Dict.values); | ||||||
| 		/* We must arrange things just right for STORE_SUBSCR.
 | 		ADDOP_I(c, BUILD_MAP, (n>255 ? 255 : n)); | ||||||
| 		   It wants the stack to look like (value) (dict) (key) */ | 		n = asdl_seq_LEN(e->v.Dict.values); | ||||||
| 		for (i = 0; i < n; i++) { | 		for (i = 0; i < n; i++) { | ||||||
| 			VISIT(c, expr,  | 			VISIT(c, expr,  | ||||||
| 				(expr_ty)asdl_seq_GET(e->v.Dict.values, i)); | 				(expr_ty)asdl_seq_GET(e->v.Dict.values, i)); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Raymond Hettinger
						Raymond Hettinger