[IMP] fields: reduce memory footprint of `field._attrs` and `column._args`

The optimization consists in sharing the dictionary when it is empty, which is
the common case.  This saves around 1.5Mb per registry.
This commit is contained in:
Raphael Collet 2015-03-11 10:16:34 +01:00
parent 4d232969a3
commit 3df7754087
2 changed files with 20 additions and 11 deletions

View File

@ -30,12 +30,13 @@ import logging
import pytz
import xmlrpclib
from openerp.tools import float_round, ustr, html_sanitize
from openerp.tools import float_round, frozendict, html_sanitize, ustr
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT as DATE_FORMAT
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT as DATETIME_FORMAT
DATE_LENGTH = len(date.today().strftime(DATE_FORMAT))
DATETIME_LENGTH = len(datetime.now().strftime(DATETIME_FORMAT))
EMPTY_DICT = frozendict()
_logger = logging.getLogger(__name__)
@ -295,7 +296,8 @@ class Field(object):
def __init__(self, string=None, **kwargs):
kwargs['string'] = string
self._attrs = {key: val for key, val in kwargs.iteritems() if val is not None}
attrs = {key: val for key, val in kwargs.iteritems() if val is not None}
self._attrs = attrs or EMPTY_DICT
# self._triggers is a set of pairs (field, path) that represents the
# computed fields that depend on `self`. When `self` is modified, it
@ -304,6 +306,15 @@ class Field(object):
self._triggers = set()
self.inverse_fields = []
def _set_attr(self, name, value):
""" Set the given field attribute, and add it to `_attrs` if necessary. """
object.__setattr__(self, name, value)
if not hasattr(type(self), name):
if self._attrs:
self._attrs[name] = value
else:
self._attrs = {name: value} # replace EMPTY_DICT
def new(self, **kwargs):
""" Return a field of the same type as `self`, with its own parameters. """
return type(self)(**kwargs)
@ -337,11 +348,9 @@ class Field(object):
if not isinstance(attrs.get('column'), (NoneType, fields.function)):
attrs.pop('store', None)
self._attrs = {}
self._attrs = EMPTY_DICT
for attr, value in attrs.iteritems():
if not hasattr(self, attr):
self._attrs[attr] = value
setattr(self, attr, value)
self._set_attr(attr, value)
if not self.string and not self.related:
# related fields get their string from their parent field
@ -481,8 +490,7 @@ class Field(object):
for attr, value in field._attrs.iteritems():
if attr not in self._attrs:
self._attrs[attr] = value
setattr(self, attr, value)
self._set_attr(attr, value)
# special case for states: copy it only for inherited fields
if not self.states and self.inherited:

View File

@ -48,11 +48,12 @@ from psycopg2 import Binary
import openerp
import openerp.tools as tools
from openerp.tools.translate import _
from openerp.tools import float_round, float_repr
from openerp.tools import html_sanitize
from openerp.tools import float_repr, float_round, frozendict, html_sanitize
import simplejson
from openerp import SUPERUSER_ID, registry
EMPTY_DICT = frozendict()
_logger = logging.getLogger(__name__)
def _symbol_set(symb):
@ -136,7 +137,7 @@ class _column(object):
if val:
setattr(self, key, val)
self._args = args
self._args = args or EMPTY_DICT
for key, val in args.iteritems():
setattr(self, key, val)