def test_clan(self):
     flags = Flags()
     flags.f.clan = CacheStatus.IS_NOT
     bitfields = Flags(asint=flags.asint).f
     self.assertEqual(bitfields.clan, CacheStatus.IS_NOT)
     bitfields.clan = CacheStatus.IS_NOT  # No change = no problem
     for state in [CacheStatus.UNKNOWN, CacheStatus.IS, CacheStatus.N_A]:
         self.assertRaises(AssertionError, lambda: setattr(bitfields, 'clan', state))
 def test_clan(self):
     flags = Flags()
     flags.f.clan = CacheStatus.IS_NOT
     bitfields = Flags(asint=flags.asint).f
     self.assertEqual(bitfields.clan, CacheStatus.IS_NOT)
     bitfields.clan = CacheStatus.IS_NOT  # No change = no problem
     for state in [CacheStatus.UNKNOWN, CacheStatus.IS, CacheStatus.N_A]:
         self.assertRaises(AssertionError, lambda: setattr(bitfields, 'clan', state))
 def test_relation(self):
     flags = Flags()
     bitfields = flags.f
     bitfields.relation = CacheStatus.IS
     self.assertEqual(bitfields.relation, CacheStatus.IS)
     flags_init = Flags(asint=flags.asint)
     bitfields_init = flags_init.f
     self.assertEqual(bitfields_init.relation, CacheStatus.IS)
     bitfields.relation = CacheStatus.IS  # No change = no problem
     bitfields_init.relation = CacheStatus.IS  # No change = no problem
     for state in [CacheStatus.UNKNOWN, CacheStatus.IS_NOT, CacheStatus.N_A]:
         self.assertRaises(AssertionError, lambda: setattr(bitfields_init, 'relation', state))
     for state in [CacheStatus.UNKNOWN, CacheStatus.IS_NOT, CacheStatus.N_A]:
         self.assertRaises(AssertionError, lambda: setattr(bitfields, 'relation', state))
 def test_initial(self):
     union = Flags()
     self.assertEqual(len(union._fields_), 2)
     flags = union.f
     asint = union.asint
     self.assertLessEqual(len(flags._fields_), SIZE_IN_BITS / 2)  # 2 bits per bitfield.
     self.assertTrue(isinstance(asint, int))
     self.assertLessEqual(asint.bit_length(), SIZE_IN_BITS)
     for field_name, field_type, field_size in flags._fields_:
         self.assertEqual(field_type, c_uint8)
         self.assertEqual(field_size, 2)
         self.assertEqual(getattr(flags, field_name), 0)
Example #5
0
    def test_speed(self):
        # The relation property is enum-based and uses a setter helper function.
        # The clan property is int-based and uses a setter helper function.
        # The multiclan property is int-based and has the code of the setter helper function
        # directly in the setter.
        #
        # The approximate run times are (for 1e6 instances):
        #           rel (enum w/)   clan (int w/)   multiclan (int w/o)
        #   set     6.4 s           0.8 s           0.7 s
        #   get     5.3 s           1.5 s           1.5 s
        #
        # The performance difference (for int-based implementations) between using a setter helper
        # (clan) and not using it (multiclan) is minimal, and setting is rare, so I decided to
        # use a setter helper function. The performance difference between enum- and int-based
        # implementations (rel and clan) seems to be more relevant, especially since there is
        # also a hit when reading (the more frequent operation). So I decided not to use enums in
        # this interface.

        # NOTE: The actual code is not anymore like described above. In order to re-run this test,
        # the code from here must be used in _flags.py:
        #
        # class State(_enum.Enum):
        #     UNKNOWN = 0
        #     IS = 1
        #     IS_NOT = 2
        #     N_A = 3
        #
        # @staticmethod
        # def _setter_helper_enum(flags, value: State) -> int:
        #     int_val = value.value
        #     assert flags == State.UNKNOWN.value or flags == int_val
        #     assert 0 <= int_val <= 3
        #     return int_val
        #
        # @property
        # def relation(self) -> State:
        #     return State(self._relation)
        #
        # @relation.setter
        # def relation(self, value: State):
        #     self._relation = self._setter_helper_enum(self._relation, value)
        #
        # @multiclan.setter
        # def multiclan(self, value: int):
        #     assert self._multiclan == CacheStatus.UNKNOWN or self._multiclan == value
        #     assert 0 <= value <= 3
        #     self._multiclan = value

        if False:
            # noinspection PyUnusedLocal
            flags = [Flags() for i in range(1000000)]

            # Commented out because of missing enum State.
            # def time_rels():
            #     # Using an enum-based interface with a setter helper function.
            #     t1 = time.process_time()
            #     for flag in flags:
            #         flag.f.relation = State.IS_NOT
            #     t2 = time.process_time()
            #     for flag in flags:
            #         self.assertEqual(flag.f.relation, State.IS_NOT)
            #     t3 = time.process_time()
            #     for flag in flags:
            #         self.assertEqual(flag.f.relation, State.IS_NOT)
            #     t4 = time.process_time()
            #     print('set', t2 - t1)
            #     print('read1', t3 - t2)
            #     print('read2', t4 - t3)
            #     print('rels (enum w/)', t4 - t1, '\n')

            def time_clans():
                # Using an int-based interface with a setter helper function.
                t1 = time.process_time()
                for flag in flags:
                    flag.f.clan = CacheStatus.IS_NOT
                t2 = time.process_time()
                for flag in flags:
                    self.assertEqual(flag.f.clan, CacheStatus.IS_NOT)
                t3 = time.process_time()
                for flag in flags:
                    self.assertEqual(flag.f.clan, CacheStatus.IS_NOT)
                t4 = time.process_time()
                print('set', t2 - t1)
                print('read1', t3 - t2)
                print('read2', t4 - t3)
                print('clans (int w/)', t4 - t1, '\n')

            def time_multiclans():
                # Using an int-based interface without a setter helper function.
                t1 = time.process_time()
                for flag in flags:
                    flag.f.multiclan = CacheStatus.IS_NOT
                t2 = time.process_time()
                for flag in flags:
                    self.assertEqual(flag.f.multiclan, CacheStatus.IS_NOT)
                t3 = time.process_time()
                for flag in flags:
                    self.assertEqual(flag.f.multiclan, CacheStatus.IS_NOT)
                t4 = time.process_time()
                print('set', t2 - t1)
                print('read1', t3 - t2)
                print('read2', t4 - t3)
                print('multiclans (int w/o)', t4 - t1, '\n')

            # time_rels()
            time_clans()
            time_multiclans()
            # time_rels()
            time_clans()
            time_multiclans()
            # time_rels()
            time_clans()
            time_multiclans()