[Checkins] SVN: DateTime/trunk/ Make DateTime a new-style class and limit its available attributes via a slots definition. The pickle size increases to 110 bytes thanks to the `ccopy_reg\n_reconstructor` stanza. But the memory size drops from 3kb to 500 bytes for each instance.
Hanno Schlichting
hannosch at hannosch.eu
Sun May 8 07:13:06 EDT 2011
Log message for revision 121577:
Make DateTime a new-style class and limit its available attributes via a slots definition. The pickle size increases to 110 bytes thanks to the `ccopy_reg\n_reconstructor` stanza. But the memory size drops from 3kb to 500 bytes for each instance.
Changed:
U DateTime/trunk/CHANGES.txt
U DateTime/trunk/src/DateTime/DateTime.py
U DateTime/trunk/src/DateTime/DateTime.txt
U DateTime/trunk/src/DateTime/tests/testDateTime.py
-=-
Modified: DateTime/trunk/CHANGES.txt
===================================================================
--- DateTime/trunk/CHANGES.txt 2011-05-08 10:42:32 UTC (rev 121576)
+++ DateTime/trunk/CHANGES.txt 2011-05-08 11:13:05 UTC (rev 121577)
@@ -4,6 +4,10 @@
3.0 (unreleased)
----------------
+- Make DateTime a new-style class and limit its available attributes via a
+ slots definition. The pickle size increases to 110 bytes thanks to the
+ `ccopy_reg\n_reconstructor` stanza. But the memory size drops from 3kb to
+ 500 bytes for each instance.
3.0a1 (2011-05-06)
------------------
Modified: DateTime/trunk/src/DateTime/DateTime.py
===================================================================
--- DateTime/trunk/src/DateTime/DateTime.py 2011-05-08 10:42:32 UTC (rev 121576)
+++ DateTime/trunk/src/DateTime/DateTime.py 2011-05-08 11:13:05 UTC (rev 121577)
@@ -281,7 +281,7 @@
return "%+03d:%02d" % divmod( (seconds/60), 60)
-class DateTime:
+class DateTime(object):
"""DateTime objects represent instants in time and provide
interfaces for controlling its representation without
affecting the absolute value of the object.
@@ -327,8 +327,8 @@
implements(IDateTime)
# For security machinery:
- __roles__=None
- __allow_access_to_unprotected_subobjects__=1
+ __roles__ = None
+ __allow_access_to_unprotected_subobjects__ = 1
# Make class-specific exceptions available as attributes.
DateError = DateError
@@ -336,6 +336,38 @@
DateTimeError = DateTimeError
SyntaxError = SyntaxError
+ # Limit the amount of instance attributes
+ __slots__ = (
+ '_timezone_naive',
+ '_tz',
+ '_pm',
+ '_pmhour',
+ '_dayoffset',
+ '_fmon',
+ '_amon',
+ '_pmon',
+ '_months',
+ '_months_a',
+ '_months_p',
+ '_fday',
+ '_aday',
+ '_pday',
+ '_days',
+ '_days_a',
+ '_days_p',
+ '_year',
+ '_month',
+ '_day',
+ '_hour',
+ '_minute',
+ '_second',
+ '_nearsec',
+ '_d',
+ '_t',
+ '_micros',
+ 'time',
+ )
+
def __init__(self, *args, **kw):
"""Return a new date-time object"""
if args and args[0] is None:
@@ -349,20 +381,17 @@
raise SyntaxError('Unable to parse %s, %s' % (args, kw))
def __getstate__(self):
- state = self.__dict__
- return (state['_micros'] / 1000000.0,
- state.get('_timezone_naive', False),
- state['_tz'])
+ return (self._micros / 1000000.0, self._timezone_naive, self._tz)
def __setstate__(self, value):
- state = self.__dict__
if isinstance(value, tuple):
self._parse_args(value[0], value[2])
- state['_micros'] = long(value[0] * 1000000)
- state['_timezone_naive'] = value[1]
+ self._micros = long(value[0] * 1000000)
+ self._timezone_naive = value[1]
else:
- state.clear()
- state.update(value)
+ for k,v in value.items():
+ if k in self.__slots__:
+ setattr(self, k, v)
def _parse_args(self, *args, **kw):
"""Return a new date-time object.
@@ -1050,7 +1079,7 @@
def __getattr__(self, name):
if '%' in name:
return strftimeFormatter(self, name)
- raise AttributeError, name
+ raise AttributeError(name)
# Conversion and comparison methods
def timeTime(self):
Modified: DateTime/trunk/src/DateTime/DateTime.txt
===================================================================
--- DateTime/trunk/src/DateTime/DateTime.txt 2011-05-08 10:42:32 UTC (rev 121576)
+++ DateTime/trunk/src/DateTime/DateTime.txt 2011-05-08 11:13:05 UTC (rev 121577)
@@ -758,7 +758,7 @@
>>> 1 - dt
Traceback (most recent call last):
...
- TypeError: unsupported operand type(s) for -: 'int' and 'instance'
+ TypeError: unsupported operand type(s) for -: 'int' and 'DateTime'
DateTimes can also be converted to integers (number of seconds since
the epoch), longs (not too long ;)) and floats:
Modified: DateTime/trunk/src/DateTime/tests/testDateTime.py
===================================================================
--- DateTime/trunk/src/DateTime/tests/testDateTime.py 2011-05-08 10:42:32 UTC (rev 121576)
+++ DateTime/trunk/src/DateTime/tests/testDateTime.py 2011-05-08 11:13:05 UTC (rev 121577)
@@ -202,19 +202,22 @@
dt = DateTime()
data = cPickle.dumps(dt, 1)
new = cPickle.loads(data)
- self.assertEqual(dt.__dict__, new.__dict__)
+ for key in DateTime.__slots__:
+ self.assertEqual(getattr(dt, key), getattr(new, key))
def test_pickle_with_tz(self):
dt = DateTime('2002/5/2 8:00am GMT+8')
data = cPickle.dumps(dt, 1)
new = cPickle.loads(data)
- self.assertEqual(dt.__dict__, new.__dict__)
+ for key in DateTime.__slots__:
+ self.assertEqual(getattr(dt, key), getattr(new, key))
def test_pickle_with_micros(self):
dt = DateTime('2002/5/2 8:00:14.123 GMT+8')
data = cPickle.dumps(dt, 1)
new = cPickle.loads(data)
- self.assertEqual(dt.__dict__, new.__dict__)
+ for key in DateTime.__slots__:
+ self.assertEqual(getattr(dt, key), getattr(new, key))
def test_pickle_old(self):
dt = DateTime('2002/5/2 8:00am GMT+0')
@@ -231,7 +234,8 @@
'\x00U\x07_pmhourq\x1dK\x08U\n_dayoffsetq\x1eK\x04U\x04timeq'
'\x1fG?\xd5UUUV\x00\x00ub.')
new = cPickle.loads(data)
- self.assertEqual(dt.__dict__, new.__dict__)
+ for key in DateTime.__slots__:
+ self.assertEqual(getattr(dt, key), getattr(new, key))
def testTZ2(self):
# Time zone manipulation test 2
More information about the checkins
mailing list