def test_mix_classes_attribute(self): import __pypy__ seen = [] for i in range(20): class A(object): def __init__(self): self.x = 42 class B(object): def __init__(self): self.x = 43 class C(object): def __init__(self): self.x = 44 l = [A(), B(), C()] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.x == 42 + i % 3 cache_counter = __pypy__.mapdict_cache_counter("x") if cache_counter == (27, 3): break # keep them alive, to make sure that on the # next try they have difference addresses seen.append((l, cache_counter)) else: assert 0, "failed: got %r" % ([got[1] for got in seen],)
def run(): import __pypy__ class A(object): x = 1 y = 2 __pypy__.reset_method_cache_counter() a = A() for i in range(100): assert a.y == 2 assert a.x == i + 1 A.x += 1 cache_counter = __pypy__.method_cache_counter("x") # XXX this is the bad case for the mapdict cache: looking up # non-method attributes from the class assert cache_counter[0] >= 450 assert cache_counter[1] >= 1 assert sum(cache_counter) == 500 __pypy__.reset_method_cache_counter() a = A() for i in range(100): assert a.y == 2 setattr(a, "a%s" % i, i) cache_counter = __pypy__.method_cache_counter("x") assert cache_counter[0] == 0 # 0 hits, because all the attributes are new
def test_mix_classes(self): import __pypy__ seen = [] for i in range(20): class A(object): def f(self): return 42 class B(object): def f(self): return 43 class C(object): def f(self): return 44 l = [A(), B(), C()] * 10 __pypy__.reset_method_cache_counter() # 'exec' to make sure that a.f() is compiled with CALL_METHOD exec """for i, a in enumerate(l): assert a.f() == 42 + i % 3 """ in locals() cache_counter = __pypy__.mapdict_cache_counter("f") if cache_counter == (27, 3): break # keep them alive, to make sure that on the # next try they have difference addresses seen.append((l, cache_counter)) else: assert 0, "failed: got %r" % ([got[1] for got in seen], )
def test_many_names(self): import __pypy__ class A(object): foo = 5 bar = 6 baz = 7 xyz = 8 stuff = 9 a = 10 foobar = 11 a = A() names = [ name for name in A.__dict__.keys() if not name.startswith('_') ] names_repeated = names * 10 result = [] __pypy__.reset_method_cache_counter() for name in names_repeated: result.append(getattr(a, name)) append_counter = __pypy__.method_cache_counter("append") names_counters = [ __pypy__.method_cache_counter(name) for name in names ] assert append_counter[0] >= 5 * len(names) for name, count in zip(names, names_counters): assert count[0] >= 5, str((name, count))
def test_mix_classes_attribute(self): import __pypy__ seen = [] for i in range(20): class A(object): def __init__(self): self.x = 42 class B(object): def __init__(self): self.x = 43 class C(object): def __init__(self): self.x = 44 l = [A(), B(), C()] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.x == 42 + i % 3 cache_counter = __pypy__.mapdict_cache_counter("x") if cache_counter == (27, 3): break # keep them alive, to make sure that on the # next try they have difference addresses seen.append((l, cache_counter)) else: assert 0, "failed: got %r" % ([got[1] for got in seen], )
def test_class_that_cannot_be_cached(self): import __pypy__ class metatype(type): pass class A(object): __metaclass__ = metatype def f(self): return 42 class B(object): def f(self): return 43 class C(object): def f(self): return 44 l = [A(), B(), C()] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 + i % 3 cache_counter = __pypy__.method_cache_counter("f") assert cache_counter[0] >= 9 assert cache_counter[1] >= 2 # should be (18, 2) assert sum(cache_counter) == 20
def test_many_names(self): import __pypy__ class A(object): foo = 5 bar = 6 baz = 7 xyz = 8 stuff = 9 a = 10 foobar = 11 a = A() names = [name for name in A.__dict__.keys() if not name.startswith('_')] names_repeated = names * 10 result = [] __pypy__.reset_method_cache_counter() for name in names_repeated: result.append(getattr(a, name)) append_counter = __pypy__.method_cache_counter("append") names_counters = [__pypy__.method_cache_counter(name) for name in names] assert append_counter[0] >= 5 * len(names) for name, count in zip(names, names_counters): assert count[0] >= 5
def test_mutate_class(self): import __pypy__ class A(object): x = 1 y = 2 __pypy__.reset_method_cache_counter() a = A() for i in range(100): assert a.y == 2 assert a.x == i + 1 A.x += 1 cache_counter = __pypy__.method_cache_counter("x") assert cache_counter[0] >= 350 assert cache_counter[1] >= 1 assert sum(cache_counter) == 400 __pypy__.reset_method_cache_counter() a = A() for i in range(100): assert a.y == 2 setattr(a, "a%s" % i, i) cache_counter = __pypy__.method_cache_counter("x") assert cache_counter[ 0] == 0 # 0 hits, because all the attributes are new
def test_mix_classes(self): import __pypy__ seen = [] for i in range(20): class A(object): def f(self): return 42 class B(object): def f(self): return 43 class C(object): def f(self): return 44 l = [A(), B(), C()] * 10 __pypy__.reset_method_cache_counter() # 'exec' to make sure that a.f() is compiled with CALL_METHOD exec """for i, a in enumerate(l): assert a.f() == 42 + i % 3 """ in locals() cache_counter = __pypy__.mapdict_cache_counter("f") if cache_counter == (27, 3): break # keep them alive, to make sure that on the # next try they have difference addresses seen.append((l, cache_counter)) else: assert 0, "failed: got %r" % ([got[1] for got in seen],)
def run(): import __pypy__ class A(object): x = 1 y = 2 __pypy__.reset_method_cache_counter() a = A() for i in range(100): assert a.y == 2 assert a.x == i + 1 A.x += 1 cache_counter = __pypy__.method_cache_counter("x") assert cache_counter[0] >= 350 assert cache_counter[1] >= 1 assert sum(cache_counter) == 400 __pypy__.reset_method_cache_counter() a = A() for i in range(100): assert a.y == 2 setattr(a, "a%s" % i, i) cache_counter = __pypy__.method_cache_counter("x") assert cache_counter[0] == 0 # 0 hits, because all the attributes are new
def test_many_names(self): import __pypy__ for j in range(20): class A(object): foo = 5 bar = 6 baz = 7 xyz = 8 stuff = 9 a = 10 foobar = 11 a = A() names = [name for name in A.__dict__.keys() if not name.startswith('_')] names.sort() names_repeated = names * 10 result = [] __pypy__.reset_method_cache_counter() for name in names_repeated: result.append(getattr(a, name)) append_counter = __pypy__.method_cache_counter("append") names_counters = [__pypy__.method_cache_counter(name) for name in names] try: assert append_counter[0] >= 10 * len(names) - 1 for name, count in zip(names, names_counters): assert count == (9, 1), str((name, count)) break except AssertionError: pass else: raise
def run(): import __pypy__ for j in range(20): class A(object): foo = 5 bar = 6 baz = 7 xyz = 8 stuff = 9 a = 10 foobar = 11 a = A() names = [name for name in A.__dict__.keys() if not name.startswith('_')] names.sort() names_repeated = names * 10 result = [] __pypy__.reset_method_cache_counter() for name in names_repeated: result.append(getattr(a, name)) append_counter = __pypy__.method_cache_counter("append") names_counters = [__pypy__.method_cache_counter(name) for name in names] try: assert append_counter[0] >= 10 * len(names) - 1 for name, count in zip(names, names_counters): assert count == (9, 1), str((name, count)) break except AssertionError: pass else: raise
def test_change_methods(self): import __pypy__ class A(object): def f(self): return 42 l = [A()] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 + i A.f = eval("lambda self: %s" % (42 + i + 1, )) cache_counter = __pypy__.method_cache_counter("f") assert cache_counter == (0, 10)
def test_change_methods(self): import __pypy__ class A(object): def f(self): return 42 l = [A()] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 + i A.f = eval("lambda self: %s" % (42 + i + 1, )) cache_counter = __pypy__.method_cache_counter("f") # the cache hits come from A.f = ..., which first does a lookup on A as # well assert cache_counter == (9, 11)
def test_change_methods(self): import __pypy__ class A(object): def f(self): return 42 l = [A()] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 + i A.f = eval("lambda self: %s" % (42 + i + 1, )) cache_counter = __pypy__.method_cache_counter("f") # the cache hits come from A.f = ..., which first does a lookup on A as # well assert cache_counter == (17, 3)
def run(): import __pypy__ laste = None for j in range(20): class A(object): def f(self): return 42 class B(object): def f(self): return 43 class C(A): pass l = [A(), B(), C()] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 + (i % 3 == 1) cache_counter = __pypy__.method_cache_counter("f") assert cache_counter[0] >= 15 assert cache_counter[1] >= 3 # should be (27, 3) assert sum(cache_counter) == 30 a = A() names = [ name for name in A.__dict__.keys() if not name.startswith('_') ] names.sort() names_repeated = names * 10 result = [] __pypy__.reset_method_cache_counter() for name in names_repeated: result.append(getattr(a, name)) append_counter = __pypy__.method_cache_counter("append") names_counters = [ __pypy__.method_cache_counter(name) for name in names ] try: assert append_counter[0] >= 10 * len(names) - 1 for name, count in zip(names, names_counters): assert count == (9, 1), str((name, count)) break except AssertionError as e: laste = e else: raise laste
def test_custom_metaclass(self): import __pypy__ class MetaA(type): def __getattribute__(self, x): return 1 def f(self): return 42 A = type.__new__(MetaA, "A", (), {"f": f}) l = [type.__getattribute__(A, "__new__")(A)] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 cache_counter = __pypy__.method_cache_counter("f") assert cache_counter[0] >= 5 assert cache_counter[1] >= 1 # should be (27, 3) assert sum(cache_counter) == 10
def run(): import __pypy__ laste = None for j in range(20): class A(object): def f(self): return 42 class B(object): def f(self): return 43 class C(A): pass l = [A(), B(), C()] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 + (i % 3 == 1) cache_counter = __pypy__.method_cache_counter("f") assert cache_counter[0] >= 15 assert cache_counter[1] >= 3 # should be (27, 3) assert sum(cache_counter) == 30 a = A() names = [name for name in A.__dict__.keys() if not name.startswith("_")] names.sort() names_repeated = names * 10 result = [] __pypy__.reset_method_cache_counter() for name in names_repeated: result.append(getattr(a, name)) append_counter = __pypy__.method_cache_counter("append") names_counters = [__pypy__.method_cache_counter(name) for name in names] try: assert append_counter[0] >= 10 * len(names) - 1 for name, count in zip(names, names_counters): assert count == (9, 1), str((name, count)) break except AssertionError as e: laste = e else: raise laste
def run(): import __pypy__ class A(object): def f(self): return 42 class B(object): def f(self): return 43 class C(A): pass l = [A(), B(), C()] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 + (i % 3 == 1) cache_counter = __pypy__.method_cache_counter("f") assert cache_counter[0] >= 15 assert cache_counter[1] >= 3 # should be (27, 3) assert sum(cache_counter) == 30
def test_subclasses(self): import __pypy__ class A(object): def f(self): return 42 class B(object): def f(self): return 43 class C(A): pass l = [A(), B(), C()] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 + (i % 3 == 1) cache_counter = __pypy__.method_cache_counter("f") assert cache_counter[0] >= 15 assert cache_counter[1] >= 3 # should be (27, 3) assert sum(cache_counter) == 30
def test_mix_classes_attribute(self): import __pypy__ class A(object): def __init__(self): self.x = 42 class B(object): def __init__(self): self.x = 43 class C(object): def __init__(self): self.x = 44 l = [A(), B(), C()] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.x == 42 + i % 3 cache_counter = __pypy__.mapdict_cache_counter("x") assert cache_counter[0] >= 15 assert cache_counter[1] >= 3 # should be (27, 3) assert sum(cache_counter) == 30
def test_custom_metaclass(self): import __pypy__ for j in range(20): class MetaA(type): def __getattribute__(self, x): return 1 def f(self): return 42 A = type.__new__(MetaA, "A", (), {"f": f}) l = [type.__getattribute__(A, "__new__")(A)] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 cache_counter = __pypy__.method_cache_counter("f") assert sum(cache_counter) == 10 if cache_counter == (9, 1): break #else the moon is misaligned, try again else: raise AssertionError("cache_counter = %r" % (cache_counter,))
def run(): import __pypy__ for j in range(20): class MetaA(type): def __getattribute__(self, x): return 1 def f(self): return 42 A = type.__new__(MetaA, "A", (), {"f": f}) l = [type.__getattribute__(A, "__new__")(A)] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): # use getattr to circumvent the mapdict cache assert getattr(a, "f")() == 42 cache_counter = __pypy__.method_cache_counter("f") assert sum(cache_counter) == 10 if cache_counter == (9, 1): break #else the moon is misaligned, try again else: raise AssertionError("cache_counter = %r" % (cache_counter,))
def test_mix_classes(self): import __pypy__ class A(object): def f(self): return 42 class B(object): def f(self): return 43 class C(object): def f(self): return 44 l = [A(), B(), C()] * 10 __pypy__.reset_method_cache_counter() # 'exec' to make sure that a.f() is compiled with CALL_METHOD exec """for i, a in enumerate(l): assert a.f() == 42 + i % 3 """ cache_counter = __pypy__.mapdict_cache_counter("f") assert cache_counter[0] >= 15 assert cache_counter[1] >= 3 # should be (27, 3) assert sum(cache_counter) == 30
def run(): import __pypy__ class A(object): def f(self): return 42 l = [A()] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 + i A.f = eval("lambda self: %s" % (42 + i + 1,)) cache_counter = __pypy__.method_cache_counter("f") # # a bit of explanation about what's going on. (1) is the line "a.f()" # and (2) is "A.f = ...". # # at line (1) we do the lookup on type(a).f # # at line (2) we do a setattr on A. However, descr_setattr does also a # lookup of type(A).f i.e. type.f, to check if by chance 'f' is a data # descriptor. # # At the first iteration: # (1) is a miss because it's the first lookup of A.f. The result is cached # # (2) is a miss because it is the first lookup of type.f. The # (non-existant) result is cached. The version of A changes, and 'f' # is changed to be a cell object, so that subsequest assignments won't # change the version of A # # At the second iteration: # (1) is a miss because the version of A changed just before # (2) is a hit, because type.f is cached. The version of A no longer changes # # At the third and subsequent iterations: # (1) is a hit, because the version of A did not change # (2) is a hit, see above assert cache_counter == (17, 3)
def run(): import __pypy__ class A(object): def f(self): return 42 l = [A()] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 + i A.f = eval("lambda self: %s" % (42 + i + 1, )) cache_counter = __pypy__.method_cache_counter("f") # # a bit of explanation about what's going on. (1) is the line "a.f()" # and (2) is "A.f = ...". # # at line (1) we do the lookup on type(a).f # # at line (2) we do a setattr on A. However, descr_setattr does also a # lookup of type(A).f i.e. type.f, to check if by chance 'f' is a data # descriptor. # # At the first iteration: # (1) is a miss because it's the first lookup of A.f. The result is cached # # (2) is a miss because it is the first lookup of type.f. The # (non-existant) result is cached. The version of A changes, and 'f' # is changed to be a cell object, so that subsequest assignments won't # change the version of A # # At the second iteration: # (1) is a miss because the version of A changed just before # (2) is a hit, because type.f is cached. The version of A no longer changes # # At the third and subsequent iterations: # (1) is a hit, because the version of A did not change # (2) is a hit, see above assert cache_counter == (17, 3)
def run(): import __pypy__ class X: pass class Y(object): pass class A(Y, X): def f(self): return 42 class B(object): def f(self): return 43 class C(object): def f(self): return 44 l = [A(), B(), C()] * 10 __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 + i % 3 cache_counter = __pypy__.method_cache_counter("f") assert cache_counter[0] >= 9 assert cache_counter[1] >= 2 # should be (18, 2) assert sum(cache_counter) == 20