(root)/
Python-3.11.7/
Tools/
scripts/
var_access_benchmark.py
       1  'Show relative speeds of local, nonlocal, global, and built-in access.'
       2  
       3  # Please leave this code so that it runs under older versions of
       4  # Python 3 (no f-strings).  That will allow benchmarking for
       5  # cross-version comparisons.  To run the benchmark on Python 2,
       6  # comment-out the nonlocal reads and writes.
       7  
       8  from collections import deque, namedtuple
       9  
      10  trials = [None] * 500
      11  steps_per_trial = 25
      12  
      13  class ESC[4;38;5;81mA(ESC[4;38;5;149mobject):
      14      def m(self):
      15          pass
      16  
      17  class ESC[4;38;5;81mB(ESC[4;38;5;149mobject):
      18      __slots__ = 'x'
      19      def __init__(self, x):
      20          self.x = x
      21  
      22  class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
      23      def __init__(self, x):
      24          self.x = x
      25  
      26  def read_local(trials=trials):
      27      v_local = 1
      28      for t in trials:
      29          v_local;    v_local;    v_local;    v_local;    v_local
      30          v_local;    v_local;    v_local;    v_local;    v_local
      31          v_local;    v_local;    v_local;    v_local;    v_local
      32          v_local;    v_local;    v_local;    v_local;    v_local
      33          v_local;    v_local;    v_local;    v_local;    v_local
      34  
      35  def make_nonlocal_reader():
      36      v_nonlocal = 1
      37      def inner(trials=trials):
      38          for t in trials:
      39              v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal
      40              v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal
      41              v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal
      42              v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal
      43              v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal
      44      inner.__name__ = 'read_nonlocal'
      45      return inner
      46  
      47  read_nonlocal = make_nonlocal_reader()
      48  
      49  v_global = 1
      50  def read_global(trials=trials):
      51      for t in trials:
      52          v_global; v_global; v_global; v_global; v_global
      53          v_global; v_global; v_global; v_global; v_global
      54          v_global; v_global; v_global; v_global; v_global
      55          v_global; v_global; v_global; v_global; v_global
      56          v_global; v_global; v_global; v_global; v_global
      57  
      58  def read_builtin(trials=trials):
      59      for t in trials:
      60          oct; oct; oct; oct; oct
      61          oct; oct; oct; oct; oct
      62          oct; oct; oct; oct; oct
      63          oct; oct; oct; oct; oct
      64          oct; oct; oct; oct; oct
      65  
      66  def read_classvar_from_class(trials=trials, A=A):
      67      A.x = 1
      68      for t in trials:
      69          A.x;    A.x;    A.x;    A.x;    A.x
      70          A.x;    A.x;    A.x;    A.x;    A.x
      71          A.x;    A.x;    A.x;    A.x;    A.x
      72          A.x;    A.x;    A.x;    A.x;    A.x
      73          A.x;    A.x;    A.x;    A.x;    A.x
      74  
      75  def read_classvar_from_instance(trials=trials, A=A):
      76      A.x = 1
      77      a = A()
      78      for t in trials:
      79          a.x;    a.x;    a.x;    a.x;    a.x
      80          a.x;    a.x;    a.x;    a.x;    a.x
      81          a.x;    a.x;    a.x;    a.x;    a.x
      82          a.x;    a.x;    a.x;    a.x;    a.x
      83          a.x;    a.x;    a.x;    a.x;    a.x
      84  
      85  def read_instancevar(trials=trials, a=C(1)):
      86      for t in trials:
      87          a.x;    a.x;    a.x;    a.x;    a.x
      88          a.x;    a.x;    a.x;    a.x;    a.x
      89          a.x;    a.x;    a.x;    a.x;    a.x
      90          a.x;    a.x;    a.x;    a.x;    a.x
      91          a.x;    a.x;    a.x;    a.x;    a.x
      92  
      93  def read_instancevar_slots(trials=trials, a=B(1)):
      94      for t in trials:
      95          a.x;    a.x;    a.x;    a.x;    a.x
      96          a.x;    a.x;    a.x;    a.x;    a.x
      97          a.x;    a.x;    a.x;    a.x;    a.x
      98          a.x;    a.x;    a.x;    a.x;    a.x
      99          a.x;    a.x;    a.x;    a.x;    a.x
     100  
     101  def read_namedtuple(trials=trials, D=namedtuple('D', ['x'])):
     102      a = D(1)
     103      for t in trials:
     104          a.x;    a.x;    a.x;    a.x;    a.x
     105          a.x;    a.x;    a.x;    a.x;    a.x
     106          a.x;    a.x;    a.x;    a.x;    a.x
     107          a.x;    a.x;    a.x;    a.x;    a.x
     108          a.x;    a.x;    a.x;    a.x;    a.x
     109  
     110  def read_boundmethod(trials=trials, a=A()):
     111      for t in trials:
     112          a.m;    a.m;    a.m;    a.m;    a.m
     113          a.m;    a.m;    a.m;    a.m;    a.m
     114          a.m;    a.m;    a.m;    a.m;    a.m
     115          a.m;    a.m;    a.m;    a.m;    a.m
     116          a.m;    a.m;    a.m;    a.m;    a.m
     117  
     118  def write_local(trials=trials):
     119      v_local = 1
     120      for t in trials:
     121          v_local = 1; v_local = 1; v_local = 1; v_local = 1; v_local = 1
     122          v_local = 1; v_local = 1; v_local = 1; v_local = 1; v_local = 1
     123          v_local = 1; v_local = 1; v_local = 1; v_local = 1; v_local = 1
     124          v_local = 1; v_local = 1; v_local = 1; v_local = 1; v_local = 1
     125          v_local = 1; v_local = 1; v_local = 1; v_local = 1; v_local = 1
     126  
     127  def make_nonlocal_writer():
     128      v_nonlocal = 1
     129      def inner(trials=trials):
     130          nonlocal v_nonlocal
     131          for t in trials:
     132              v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1
     133              v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1
     134              v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1
     135              v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1
     136              v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1
     137      inner.__name__ = 'write_nonlocal'
     138      return inner
     139  
     140  write_nonlocal = make_nonlocal_writer()
     141  
     142  def write_global(trials=trials):
     143      global v_global
     144      for t in trials:
     145          v_global = 1; v_global = 1; v_global = 1; v_global = 1; v_global = 1
     146          v_global = 1; v_global = 1; v_global = 1; v_global = 1; v_global = 1
     147          v_global = 1; v_global = 1; v_global = 1; v_global = 1; v_global = 1
     148          v_global = 1; v_global = 1; v_global = 1; v_global = 1; v_global = 1
     149          v_global = 1; v_global = 1; v_global = 1; v_global = 1; v_global = 1
     150  
     151  def write_classvar(trials=trials, A=A):
     152      for t in trials:
     153          A.x = 1;    A.x = 1;    A.x = 1;    A.x = 1;    A.x = 1
     154          A.x = 1;    A.x = 1;    A.x = 1;    A.x = 1;    A.x = 1
     155          A.x = 1;    A.x = 1;    A.x = 1;    A.x = 1;    A.x = 1
     156          A.x = 1;    A.x = 1;    A.x = 1;    A.x = 1;    A.x = 1
     157          A.x = 1;    A.x = 1;    A.x = 1;    A.x = 1;    A.x = 1
     158  
     159  def write_instancevar(trials=trials, a=C(1)):
     160      for t in trials:
     161          a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1
     162          a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1
     163          a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1
     164          a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1
     165          a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1
     166  
     167  def write_instancevar_slots(trials=trials, a=B(1)):
     168      for t in trials:
     169          a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1
     170          a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1
     171          a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1
     172          a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1
     173          a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1;    a.x = 1
     174  
     175  def read_list(trials=trials, a=[1]):
     176      for t in trials:
     177          a[0];   a[0];   a[0];   a[0];   a[0]
     178          a[0];   a[0];   a[0];   a[0];   a[0]
     179          a[0];   a[0];   a[0];   a[0];   a[0]
     180          a[0];   a[0];   a[0];   a[0];   a[0]
     181          a[0];   a[0];   a[0];   a[0];   a[0]
     182  
     183  def read_deque(trials=trials, a=deque([1])):
     184      for t in trials:
     185          a[0];   a[0];   a[0];   a[0];   a[0]
     186          a[0];   a[0];   a[0];   a[0];   a[0]
     187          a[0];   a[0];   a[0];   a[0];   a[0]
     188          a[0];   a[0];   a[0];   a[0];   a[0]
     189          a[0];   a[0];   a[0];   a[0];   a[0]
     190  
     191  def read_dict(trials=trials, a={0: 1}):
     192      for t in trials:
     193          a[0];   a[0];   a[0];   a[0];   a[0]
     194          a[0];   a[0];   a[0];   a[0];   a[0]
     195          a[0];   a[0];   a[0];   a[0];   a[0]
     196          a[0];   a[0];   a[0];   a[0];   a[0]
     197          a[0];   a[0];   a[0];   a[0];   a[0]
     198  
     199  def read_strdict(trials=trials, a={'key': 1}):
     200      for t in trials:
     201          a['key'];   a['key'];   a['key'];   a['key'];   a['key']
     202          a['key'];   a['key'];   a['key'];   a['key'];   a['key']
     203          a['key'];   a['key'];   a['key'];   a['key'];   a['key']
     204          a['key'];   a['key'];   a['key'];   a['key'];   a['key']
     205          a['key'];   a['key'];   a['key'];   a['key'];   a['key']
     206  
     207  def list_append_pop(trials=trials, a=[1]):
     208      ap, pop = a.append, a.pop
     209      for t in trials:
     210          ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop()
     211          ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop()
     212          ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop()
     213          ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop()
     214          ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop()
     215  
     216  def deque_append_pop(trials=trials, a=deque([1])):
     217      ap, pop = a.append, a.pop
     218      for t in trials:
     219          ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop()
     220          ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop()
     221          ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop()
     222          ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop()
     223          ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop()
     224  
     225  def deque_append_popleft(trials=trials, a=deque([1])):
     226      ap, pop = a.append, a.popleft
     227      for t in trials:
     228          ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop();
     229          ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop();
     230          ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop();
     231          ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop();
     232          ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop(); ap(1); pop();
     233  
     234  def write_list(trials=trials, a=[1]):
     235      for t in trials:
     236          a[0]=1; a[0]=1; a[0]=1; a[0]=1; a[0]=1
     237          a[0]=1; a[0]=1; a[0]=1; a[0]=1; a[0]=1
     238          a[0]=1; a[0]=1; a[0]=1; a[0]=1; a[0]=1
     239          a[0]=1; a[0]=1; a[0]=1; a[0]=1; a[0]=1
     240          a[0]=1; a[0]=1; a[0]=1; a[0]=1; a[0]=1
     241  
     242  def write_deque(trials=trials, a=deque([1])):
     243      for t in trials:
     244          a[0]=1; a[0]=1; a[0]=1; a[0]=1; a[0]=1
     245          a[0]=1; a[0]=1; a[0]=1; a[0]=1; a[0]=1
     246          a[0]=1; a[0]=1; a[0]=1; a[0]=1; a[0]=1
     247          a[0]=1; a[0]=1; a[0]=1; a[0]=1; a[0]=1
     248          a[0]=1; a[0]=1; a[0]=1; a[0]=1; a[0]=1
     249  
     250  def write_dict(trials=trials, a={0: 1}):
     251      for t in trials:
     252          a[0]=1; a[0]=1; a[0]=1; a[0]=1; a[0]=1
     253          a[0]=1; a[0]=1; a[0]=1; a[0]=1; a[0]=1
     254          a[0]=1; a[0]=1; a[0]=1; a[0]=1; a[0]=1
     255          a[0]=1; a[0]=1; a[0]=1; a[0]=1; a[0]=1
     256          a[0]=1; a[0]=1; a[0]=1; a[0]=1; a[0]=1
     257  
     258  def write_strdict(trials=trials, a={'key': 1}):
     259      for t in trials:
     260          a['key']=1; a['key']=1; a['key']=1; a['key']=1; a['key']=1
     261          a['key']=1; a['key']=1; a['key']=1; a['key']=1; a['key']=1
     262          a['key']=1; a['key']=1; a['key']=1; a['key']=1; a['key']=1
     263          a['key']=1; a['key']=1; a['key']=1; a['key']=1; a['key']=1
     264          a['key']=1; a['key']=1; a['key']=1; a['key']=1; a['key']=1
     265  
     266  def loop_overhead(trials=trials):
     267      for t in trials:
     268          pass
     269  
     270  
     271  if __name__=='__main__':
     272  
     273      from timeit import Timer
     274  
     275      for f in [
     276              'Variable and attribute read access:',
     277              read_local, read_nonlocal, read_global, read_builtin,
     278              read_classvar_from_class, read_classvar_from_instance,
     279              read_instancevar, read_instancevar_slots,
     280              read_namedtuple, read_boundmethod,
     281              '\nVariable and attribute write access:',
     282              write_local, write_nonlocal, write_global,
     283              write_classvar, write_instancevar, write_instancevar_slots,
     284              '\nData structure read access:',
     285              read_list, read_deque, read_dict, read_strdict,
     286              '\nData structure write access:',
     287              write_list, write_deque, write_dict, write_strdict,
     288              '\nStack (or queue) operations:',
     289              list_append_pop, deque_append_pop, deque_append_popleft,
     290              '\nTiming loop overhead:',
     291              loop_overhead]:
     292          if isinstance(f, str):
     293              print(f)
     294              continue
     295          timing = min(Timer(f).repeat(7, 1000))
     296          timing *= 1000000 / (len(trials) * steps_per_trial)
     297          print('{:6.1f} ns\t{}'.format(timing, f.__name__))