----- Original Message -----
> From: Steven D'Aprano <st...@pearwood.info> > To: tutor@python.org > Cc: > Sent: Friday, June 13, 2014 3:08 PM > Subject: Re: [Tutor] global variables/constants versus volatile > variables/constants > > On Fri, Jun 13, 2014 at 05:10:28AM -0700, Albert-Jan Roskam wrote: > >> The other day I used collections.namedtuple and I re-initialized >> Record (see below) with every function*) call. Bad idea! It looks >> nicer because I did not need a global (and globals are baaad, mkay?), >> but it was *much* slower. I processed a log of a few million lines, I >> think. >> >> # bad --> time-consuming >> import collections >> >> def do_something_with(raw_record): >> Record = collections.namedtuple("_", " > ".join("v%%03d" % i for i in range(100))) >> return Record(*raw_record.split()) > > Look at how much work you do here. First, you create a long string of > the form: > > "v000 v001 v002 v003 ... v099" > > representing 1000 v-digits names. Then you create a brand new Record > class that takes those 100 v-digits names as arguments. Creating that > class requires building a string, parsing it as Python code, and then > running it. (You're not expected to know that, but if you read the > source code for namedtuple you will see that's how it works.) So > creating that class is slow. Every time you call the function, it builds > a new "v000 ... v099" string, from scratch, then builds a new class, > also from scratch, and finally populates an instance of that class with > 100 values from the raw_record. > > Only that last step needs to be done inside the function. Hmm, if I create the namedtuple with 'verbose=True' it *really* makes clear why it took so much longer. (what's '_property' btw? I know 'property' and the newer decorator wih the same name, but not _property). In [1]: import collections In [2]: Record = collections.namedtuple("_", " ".join("v%03d" % i for i in range(100)),verbose=True) class _(tuple): '_(v000, v001, v002, v003, v004, v005, v006, v007, v008, v009, v010, v011, v012, v013, v014, v015, v016, v017, v018, v019, v020, v021, v022, v023, v024, v025, v026, v027, v028, v029, v030, v031, v032, v033, v034, v035, v036, v037, v038, v039, v040, v041, v042, v043, v044, v045, v046, v047, v048, v049, v050, v051, v052, v053, v054, v055, v056, v057, v058, v059, v060, v061, v062, v063, v064, v065, v066, v067, v068, v069, v070, v071, v072, v073, v074, v075, v076, v077, v078, v079, v080, v081, v082, v083, v084, v085, v086, v087, v088, v089, v090, v091, v092, v093, v094, v095, v096, v097, v098, v099)' __slots__ = () _fields = ('v000', 'v001', 'v002', 'v003', 'v004', 'v005', 'v006', 'v007', 'v008', 'v009', 'v010', 'v011', 'v012', 'v013', 'v014', 'v015', 'v016', 'v017', 'v018', 'v019', 'v020', 'v021', 'v022', 'v023', 'v024', 'v025', 'v026', 'v027', 'v028', 'v029', 'v030', 'v031', 'v032', 'v033', 'v034', 'v035', 'v036', 'v037', 'v038', 'v039', 'v040', 'v041', 'v042', 'v043', 'v044', 'v045', 'v046', 'v047', 'v048', 'v049', 'v050', 'v051', 'v052', 'v053', 'v054', 'v055', 'v056', 'v057', 'v058', 'v059', 'v060', 'v061', 'v062', 'v063', 'v064', 'v065', 'v066', 'v067', 'v068', 'v069', 'v070', 'v071', 'v072', 'v073', 'v074', 'v075', 'v076', 'v077', 'v078', 'v079', 'v080', 'v081', 'v082', 'v083', 'v084', 'v085', 'v086', 'v087', 'v088', 'v089', 'v090', 'v091', 'v092', 'v093', 'v094', 'v095', 'v096', 'v097', 'v098', 'v099') def __new__(_cls, v000, v001, v002, v003, v004, v005, v006, v007, v008, v009, v010, v011, v012, v013, v014, v015, v016, v017, v018, v019, v020, v021, v022, v023, v024, v025, v026, v027, v028, v029, v030, v031, v032, v033, v034, v035, v036, v037, v038, v039, v040, v041, v042, v043, v044, v045, v046, v047, v048, v049, v050, v051, v052, v053, v054, v055, v056, v057, v058, v059, v060, v061, v062, v063, v064, v065, v066, v067, v068, v069, v070, v071, v072, v073, v074, v075, v076, v077, v078, v079, v080, v081, v082, v083, v084, v085, v086, v087, v088, v089, v090, v091, v092, v093, v094, v095, v096, v097, v098, v099): 'Create new instance of _(v000, v001, v002, v003, v004, v005, v006, v007, v008, v009, v010, v011, v012, v013, v014, v015, v016, v017, v018, v019, v020, v021, v022, v023, v024, v025, v026, v027, v028, v029, v030, v031, v032, v033, v034, v035, v036, v037, v038, v039, v040, v041, v042, v043, v044, v045, v046, v047, v048, v049, v050, v051, v052, v053, v054, v055, v056, v057, v058, v059, v060, v061, v062, v063, v064, v065, v066, v067, v068, v069, v070, v071, v072, v073, v074, v075, v076, v077, v078, v079, v080, v081, v082, v083, v084, v085, v086, v087, v088, v089, v090, v091, v092, v093, v094, v095, v096, v097, v098, v099)' return _tuple.__new__(_cls, (v000, v001, v002, v003, v004, v005, v006, v007, v008, v009, v010, v011, v012, v013, v014, v015, v016, v017, v018, v019, v020, v021, v022, v023, v024, v025, v026, v027, v028, v029, v030, v031, v032, v033, v034, v035, v036, v037, v038, v039, v040, v041, v042, v043, v044, v045, v046, v047, v048, v049, v050, v051, v052, v053, v054, v055, v056, v057, v058, v059, v060, v061, v062, v063, v064, v065, v066, v067, v068, v069, v070, v071, v072, v073, v074, v075, v076, v077, v078, v079, v080, v081, v082, v083, v084, v085, v086, v087, v088, v089, v090, v091, v092, v093, v094, v095, v096, v097, v098, v099)) @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new _ object from a sequence or iterable' result = new(cls, iterable) if len(result) != 100: raise TypeError('Expected 100 arguments, got %d' % len(result)) return result def __repr__(self): 'Return a nicely formatted representation string' return '_(v000=%r, v001=%r, v002=%r, v003=%r, v004=%r, v005=%r, v006=%r, v007=%r, v008=%r, v009=%r, v010=%r, v011=%r, v012=%r, v013=%r, v014=%r, v015=%r, v016=%r, v017=%r, v018=%r, v019=%r, v020=%r, v021=%r, v022=%r, v023=%r, v024=%r, v025=%r, v026=%r, v027=%r, v028=%r, v029=%r, v030=%r, v031=%r, v032=%r, v033=%r, v034=%r, v035=%r, v036=%r, v037=%r, v038=%r, v039=%r, v040=%r, v041=%r, v042=%r, v043=%r, v044=%r, v045=%r, v046=%r, v047=%r, v048=%r, v049=%r, v050=%r, v051=%r, v052=%r, v053=%r, v054=%r, v055=%r, v056=%r, v057=%r, v058=%r, v059=%r, v060=%r, v061=%r, v062=%r, v063=%r, v064=%r, v065=%r, v066=%r, v067=%r, v068=%r, v069=%r, v070=%r, v071=%r, v072=%r, v073=%r, v074=%r, v075=%r, v076=%r, v077=%r, v078=%r, v079=%r, v080=%r, v081=%r, v082=%r, v083=%r, v084=%r, v085=%r, v086=%r, v087=%r, v088=%r, v089=%r, v090=%r, v091=%r, v092=%r, v093=%r, v094=%r, v095=%r, v096=%r, v097=%r, v098=%r, v099=%r)' % self def _asdict(self): 'Return a new OrderedDict which maps field names to their values' return OrderedDict(zip(self._fields, self)) __dict__ = property(_asdict) def _replace(_self, **kwds): 'Return a new _ object replacing specified fields with new values' result = _self._make(map(kwds.pop, ('v000', 'v001', 'v002', 'v003', 'v004', 'v005', 'v006', 'v007', 'v008', 'v009', 'v010', 'v011', 'v012', 'v013', 'v014', 'v015', 'v016', 'v017', 'v018', 'v019', 'v020', 'v021', 'v022', 'v023', 'v024', 'v025', 'v026', 'v027', 'v028', 'v029', 'v030', 'v031', 'v032', 'v033', 'v034', 'v035', 'v036', 'v037', 'v038', 'v039', 'v040', 'v041', 'v042', 'v043', 'v044', 'v045', 'v046', 'v047', 'v048', 'v049', 'v050', 'v051', 'v052', 'v053', 'v054', 'v055', 'v056', 'v057', 'v058', 'v059', 'v060', 'v061', 'v062', 'v063', 'v064', 'v065', 'v066', 'v067', 'v068', 'v069', 'v070', 'v071', 'v072', 'v073', 'v074', 'v075', 'v076', 'v077', 'v078', 'v079', 'v080', 'v081', 'v082', 'v083', 'v084', 'v085', 'v086', 'v087', 'v088', 'v089', 'v090', 'v091', 'v092', 'v093', 'v094', 'v095', 'v096', 'v097', 'v098', 'v099'), _self)) if kwds: raise ValueError('Got unexpected field names: %r' % kwds.keys()) return result def __getnewargs__(self): 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) v000 = _property(_itemgetter(0), doc='Alias for field number 0') v001 = _property(_itemgetter(1), doc='Alias for field number 1') v002 = _property(_itemgetter(2), doc='Alias for field number 2') v003 = _property(_itemgetter(3), doc='Alias for field number 3') v004 = _property(_itemgetter(4), doc='Alias for field number 4') v005 = _property(_itemgetter(5), doc='Alias for field number 5') v006 = _property(_itemgetter(6), doc='Alias for field number 6') v007 = _property(_itemgetter(7), doc='Alias for field number 7') v008 = _property(_itemgetter(8), doc='Alias for field number 8') v009 = _property(_itemgetter(9), doc='Alias for field number 9') v010 = _property(_itemgetter(10), doc='Alias for field number 10') v011 = _property(_itemgetter(11), doc='Alias for field number 11') v012 = _property(_itemgetter(12), doc='Alias for field number 12') v013 = _property(_itemgetter(13), doc='Alias for field number 13') v014 = _property(_itemgetter(14), doc='Alias for field number 14') v015 = _property(_itemgetter(15), doc='Alias for field number 15') v016 = _property(_itemgetter(16), doc='Alias for field number 16') v017 = _property(_itemgetter(17), doc='Alias for field number 17') v018 = _property(_itemgetter(18), doc='Alias for field number 18') v019 = _property(_itemgetter(19), doc='Alias for field number 19') v020 = _property(_itemgetter(20), doc='Alias for field number 20') v021 = _property(_itemgetter(21), doc='Alias for field number 21') v022 = _property(_itemgetter(22), doc='Alias for field number 22') v023 = _property(_itemgetter(23), doc='Alias for field number 23') v024 = _property(_itemgetter(24), doc='Alias for field number 24') v025 = _property(_itemgetter(25), doc='Alias for field number 25') v026 = _property(_itemgetter(26), doc='Alias for field number 26') v027 = _property(_itemgetter(27), doc='Alias for field number 27') v028 = _property(_itemgetter(28), doc='Alias for field number 28') v029 = _property(_itemgetter(29), doc='Alias for field number 29') v030 = _property(_itemgetter(30), doc='Alias for field number 30') v031 = _property(_itemgetter(31), doc='Alias for field number 31') v032 = _property(_itemgetter(32), doc='Alias for field number 32') v033 = _property(_itemgetter(33), doc='Alias for field number 33') v034 = _property(_itemgetter(34), doc='Alias for field number 34') v035 = _property(_itemgetter(35), doc='Alias for field number 35') v036 = _property(_itemgetter(36), doc='Alias for field number 36') v037 = _property(_itemgetter(37), doc='Alias for field number 37') v038 = _property(_itemgetter(38), doc='Alias for field number 38') v039 = _property(_itemgetter(39), doc='Alias for field number 39') v040 = _property(_itemgetter(40), doc='Alias for field number 40') v041 = _property(_itemgetter(41), doc='Alias for field number 41') v042 = _property(_itemgetter(42), doc='Alias for field number 42') v043 = _property(_itemgetter(43), doc='Alias for field number 43') v044 = _property(_itemgetter(44), doc='Alias for field number 44') v045 = _property(_itemgetter(45), doc='Alias for field number 45') v046 = _property(_itemgetter(46), doc='Alias for field number 46') v047 = _property(_itemgetter(47), doc='Alias for field number 47') v048 = _property(_itemgetter(48), doc='Alias for field number 48') v049 = _property(_itemgetter(49), doc='Alias for field number 49') v050 = _property(_itemgetter(50), doc='Alias for field number 50') v051 = _property(_itemgetter(51), doc='Alias for field number 51') v052 = _property(_itemgetter(52), doc='Alias for field number 52') v053 = _property(_itemgetter(53), doc='Alias for field number 53') v054 = _property(_itemgetter(54), doc='Alias for field number 54') v055 = _property(_itemgetter(55), doc='Alias for field number 55') v056 = _property(_itemgetter(56), doc='Alias for field number 56') v057 = _property(_itemgetter(57), doc='Alias for field number 57') v058 = _property(_itemgetter(58), doc='Alias for field number 58') v059 = _property(_itemgetter(59), doc='Alias for field number 59') v060 = _property(_itemgetter(60), doc='Alias for field number 60') v061 = _property(_itemgetter(61), doc='Alias for field number 61') v062 = _property(_itemgetter(62), doc='Alias for field number 62') v063 = _property(_itemgetter(63), doc='Alias for field number 63') v064 = _property(_itemgetter(64), doc='Alias for field number 64') v065 = _property(_itemgetter(65), doc='Alias for field number 65') v066 = _property(_itemgetter(66), doc='Alias for field number 66') v067 = _property(_itemgetter(67), doc='Alias for field number 67') v068 = _property(_itemgetter(68), doc='Alias for field number 68') v069 = _property(_itemgetter(69), doc='Alias for field number 69') v070 = _property(_itemgetter(70), doc='Alias for field number 70') v071 = _property(_itemgetter(71), doc='Alias for field number 71') v072 = _property(_itemgetter(72), doc='Alias for field number 72') v073 = _property(_itemgetter(73), doc='Alias for field number 73') v074 = _property(_itemgetter(74), doc='Alias for field number 74') v075 = _property(_itemgetter(75), doc='Alias for field number 75') v076 = _property(_itemgetter(76), doc='Alias for field number 76') v077 = _property(_itemgetter(77), doc='Alias for field number 77') v078 = _property(_itemgetter(78), doc='Alias for field number 78') v079 = _property(_itemgetter(79), doc='Alias for field number 79') v080 = _property(_itemgetter(80), doc='Alias for field number 80') v081 = _property(_itemgetter(81), doc='Alias for field number 81') v082 = _property(_itemgetter(82), doc='Alias for field number 82') v083 = _property(_itemgetter(83), doc='Alias for field number 83') v084 = _property(_itemgetter(84), doc='Alias for field number 84') v085 = _property(_itemgetter(85), doc='Alias for field number 85') v086 = _property(_itemgetter(86), doc='Alias for field number 86') v087 = _property(_itemgetter(87), doc='Alias for field number 87') v088 = _property(_itemgetter(88), doc='Alias for field number 88') v089 = _property(_itemgetter(89), doc='Alias for field number 89') v090 = _property(_itemgetter(90), doc='Alias for field number 90') v091 = _property(_itemgetter(91), doc='Alias for field number 91') v092 = _property(_itemgetter(92), doc='Alias for field number 92') v093 = _property(_itemgetter(93), doc='Alias for field number 93') v094 = _property(_itemgetter(94), doc='Alias for field number 94') v095 = _property(_itemgetter(95), doc='Alias for field number 95') v096 = _property(_itemgetter(96), doc='Alias for field number 96') v097 = _property(_itemgetter(97), doc='Alias for field number 97') v098 = _property(_itemgetter(98), doc='Alias for field number 98') v099 = _property(_itemgetter(99), doc='Alias for field number 99') <snip> > Global variables aren't bad because Moses came down from the mountains > with a stone tablet that declares that they are bad. They're bad because > they cause excessive coupling, they operate by side-effect, they spoil > idepotent code, and they are implicit instead of explicit. LOL :-) Textbooks conditioned me to have a generalized fear of globals. Like Little Albert: http://en.wikipedia.org/wiki/Little_Albert_experiment :-) >> def do_something_with(raw_record): >> return Record(*raw_record.split()) > > Much more sensible! > > > > > -- > Steven _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor