PyCyBase 0.1.10__cp315-cp315-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cbase/__infra__.pxd +6 -0
- cbase/__init__.pxd +6 -0
- cbase/__init__.py +31 -0
- cbase/allocator_protocol/__infra__.pxd +65 -0
- cbase/allocator_protocol/__init__.pxd +65 -0
- cbase/allocator_protocol/__init__.py +45 -0
- cbase/allocator_protocol/c_allocator_protocol.c +31874 -0
- cbase/allocator_protocol/c_allocator_protocol.cp315-win_amd64.pyd +0 -0
- cbase/allocator_protocol/c_allocator_protocol.h +352 -0
- cbase/allocator_protocol/c_allocator_protocol.pxd +66 -0
- cbase/allocator_protocol/c_allocator_protocol.pyi +144 -0
- cbase/allocator_protocol/c_allocator_protocol.pyx +209 -0
- cbase/allocator_protocol/c_heap_allocator.c +38225 -0
- cbase/allocator_protocol/c_heap_allocator.cp315-win_amd64.pyd +0 -0
- cbase/allocator_protocol/c_heap_allocator.h +554 -0
- cbase/allocator_protocol/c_heap_allocator.pxd +105 -0
- cbase/allocator_protocol/c_heap_allocator.pyi +161 -0
- cbase/allocator_protocol/c_heap_allocator.pyx +303 -0
- cbase/allocator_protocol/c_nt_shm_allocator.c +33455 -0
- cbase/allocator_protocol/c_nt_shm_allocator.cp315-win_amd64.pyd +0 -0
- cbase/allocator_protocol/c_nt_shm_allocator.h +1105 -0
- cbase/allocator_protocol/c_nt_shm_allocator.pxd +110 -0
- cbase/allocator_protocol/c_nt_shm_allocator.pyx +223 -0
- cbase/allocator_protocol/c_shm_allocator.h +1270 -0
- cbase/allocator_protocol/c_shm_allocator.pxd +150 -0
- cbase/allocator_protocol/c_shm_allocator.pyi +299 -0
- cbase/allocator_protocol/c_shm_allocator.pyx +445 -0
- cbase/allocator_protocol/c_shm_comp.c +4654 -0
- cbase/allocator_protocol/c_shm_comp.cp315-win_amd64.pyd +0 -0
- cbase/allocator_protocol/c_shm_comp.h +49 -0
- cbase/allocator_protocol/c_shm_comp.pxd +46 -0
- cbase/allocator_protocol/c_shm_comp.pyx +1 -0
- cbase/backports/__infra__.pxd +17 -0
- cbase/backports/__init__.pxd +17 -0
- cbase/backports/__init__.py +9 -0
- cbase/backports/pydict.h +55 -0
- cbase/backports/pydict.pxd +5 -0
- cbase/backports/pylong.c +9965 -0
- cbase/backports/pylong.cp315-win_amd64.pyd +0 -0
- cbase/backports/pylong.h +79 -0
- cbase/backports/pylong.pxd +23 -0
- cbase/backports/pylong.pyx +61 -0
- cbase/bytemap/__infra__.pxd +42 -0
- cbase/bytemap/__init__.pxd +42 -0
- cbase/bytemap/__init__.py +21 -0
- cbase/bytemap/c_bytemap.c +52151 -0
- cbase/bytemap/c_bytemap.cp315-win_amd64.pyd +0 -0
- cbase/bytemap/c_bytemap.h +867 -0
- cbase/bytemap/c_bytemap.pxd +370 -0
- cbase/bytemap/c_bytemap.pyx +1760 -0
- cbase/bytemap/xxh3.h +55 -0
- cbase/bytemap/xxhash.c +42 -0
- cbase/bytemap/xxhash.h +7487 -0
- cbase/config_view.c +7253 -0
- cbase/config_view.cp315-win_amd64.pyd +0 -0
- cbase/config_view.pyx +85 -0
- cbase/env.c +11120 -0
- cbase/env.cp315-win_amd64.pyd +0 -0
- cbase/env.pxd +8 -0
- cbase/env.pyi +48 -0
- cbase/env.pyx +46 -0
- cbase/includes/cbase/allocator_protocol/c_allocator_protocol.c +31874 -0
- cbase/includes/cbase/allocator_protocol/c_allocator_protocol.h +352 -0
- cbase/includes/cbase/allocator_protocol/c_heap_allocator.c +38225 -0
- cbase/includes/cbase/allocator_protocol/c_heap_allocator.h +554 -0
- cbase/includes/cbase/allocator_protocol/c_nt_shm_allocator.c +33455 -0
- cbase/includes/cbase/allocator_protocol/c_nt_shm_allocator.h +1105 -0
- cbase/includes/cbase/allocator_protocol/c_shm_allocator.h +1270 -0
- cbase/includes/cbase/allocator_protocol/c_shm_comp.c +4654 -0
- cbase/includes/cbase/allocator_protocol/c_shm_comp.h +49 -0
- cbase/includes/cbase/backports/pydict.h +55 -0
- cbase/includes/cbase/backports/pylong.c +9965 -0
- cbase/includes/cbase/backports/pylong.h +79 -0
- cbase/includes/cbase/bytemap/c_bytemap.c +52151 -0
- cbase/includes/cbase/bytemap/c_bytemap.h +867 -0
- cbase/includes/cbase/bytemap/xxh3.h +55 -0
- cbase/includes/cbase/bytemap/xxhash.c +42 -0
- cbase/includes/cbase/bytemap/xxhash.h +7487 -0
- cbase/includes/cbase/config_view.c +7253 -0
- cbase/includes/cbase/env.c +11120 -0
- cbase/includes/cbase/int128.h +81 -0
- cbase/includes/cbase/intern_string/c_intern_string.c +28138 -0
- cbase/includes/cbase/intern_string/c_intern_string.h +614 -0
- cbase/includes/cbase/nt/pthread_nt_compat.h +102 -0
- cbase/includes/cbase/nt/regex_nt_compat.h +133 -0
- cbase/includes/cbase/nt/time_sched_nt_compat.h +32 -0
- cbase/int128.h +81 -0
- cbase/int128.pxd +15 -0
- cbase/intern_string/BENCHMARK.md +157 -0
- cbase/intern_string/__infra__.pxd +13 -0
- cbase/intern_string/__init__.pxd +13 -0
- cbase/intern_string/__init__.py +19 -0
- cbase/intern_string/c_intern_string.c +28138 -0
- cbase/intern_string/c_intern_string.cp315-win_amd64.pyd +0 -0
- cbase/intern_string/c_intern_string.h +614 -0
- cbase/intern_string/c_intern_string.pxd +121 -0
- cbase/intern_string/c_intern_string.pyi +376 -0
- cbase/intern_string/c_intern_string.pyx +765 -0
- cbase/nt/pthread_nt_compat.h +102 -0
- cbase/nt/regex_nt_compat.h +133 -0
- cbase/nt/time_sched_nt_compat.h +32 -0
- pycybase-0.1.10.dist-info/METADATA +190 -0
- pycybase-0.1.10.dist-info/RECORD +105 -0
- pycybase-0.1.10.dist-info/WHEEL +5 -0
- pycybase-0.1.10.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
from libc.stdint cimport uint64_t, uint8_t
|
|
2
|
+
|
|
3
|
+
from cbase.allocator_protocol.c_allocator_protocol cimport allocator_protocol
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
cdef extern from "cbase/intern_string/c_intern_string.h":
|
|
7
|
+
# === Constants ===
|
|
8
|
+
size_t ISTR_INITIAL_CAPACITY
|
|
9
|
+
uint64_t FNV_OFFSET_BASIS
|
|
10
|
+
uint64_t FNV_PRIME
|
|
11
|
+
uint8_t ISTR_USE_BYTEMAP_BACKEND
|
|
12
|
+
|
|
13
|
+
ctypedef struct pthread_mutex_t:
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
# === Structs ===
|
|
17
|
+
ctypedef struct istr_entry:
|
|
18
|
+
const char* key
|
|
19
|
+
size_t key_length
|
|
20
|
+
uint64_t hash
|
|
21
|
+
istr_entry* next
|
|
22
|
+
|
|
23
|
+
ctypedef struct istr_map:
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
int pthread_mutex_init(pthread_mutex_t* mutex, void* attr) noexcept nogil
|
|
27
|
+
int pthread_mutex_lock(pthread_mutex_t* mutex) noexcept nogil
|
|
28
|
+
int pthread_mutex_unlock(pthread_mutex_t* mutex) noexcept nogil
|
|
29
|
+
int pthread_mutex_destroy(pthread_mutex_t* mutex) noexcept nogil
|
|
30
|
+
|
|
31
|
+
# === Unified accessors ===
|
|
32
|
+
size_t istr_map_size(const istr_map* map) noexcept nogil
|
|
33
|
+
istr_entry* istr_map_first(const istr_map* map) noexcept nogil
|
|
34
|
+
size_t istr_map_capacity(const istr_map* map) noexcept nogil
|
|
35
|
+
|
|
36
|
+
# === Hash ===
|
|
37
|
+
uint64_t fnv1a_hash(const char* key, size_t key_length)
|
|
38
|
+
|
|
39
|
+
# === Map lifecycle ===
|
|
40
|
+
istr_map* c_istr_map_new(size_t capacity, allocator_protocol* allocator)
|
|
41
|
+
void c_istr_map_free(istr_map* imap)
|
|
42
|
+
|
|
43
|
+
# === Extend ===
|
|
44
|
+
int c_istr_map_extend(istr_map* imap, size_t new_capacity)
|
|
45
|
+
int c_istr_map_extend_synced(istr_map* imap, size_t new_capacity)
|
|
46
|
+
|
|
47
|
+
# === Lookup ===
|
|
48
|
+
const istr_entry* c_istr_map_lookup(const istr_map* imap, const char* key, size_t key_length)
|
|
49
|
+
const istr_entry* c_istr_map_lookup_synced(const istr_map* imap, const char* key, size_t key_length)
|
|
50
|
+
|
|
51
|
+
# === Intern ===
|
|
52
|
+
const char* c_istr(istr_map* imap, const char* key, size_t key_length, const istr_entry** out_entry)
|
|
53
|
+
const char* c_istr_synced(istr_map* imap, const char* key, size_t key_length, const istr_entry** out_entry)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
cdef class InternString:
|
|
57
|
+
cdef readonly InternStringPool pool
|
|
58
|
+
cdef const char* key
|
|
59
|
+
cdef uint64_t hash
|
|
60
|
+
|
|
61
|
+
@staticmethod
|
|
62
|
+
cdef InternString c_from_entry(const istr_entry* entry, InternStringPool pool)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
cdef class InternStringPool:
|
|
66
|
+
cdef istr_map* pool
|
|
67
|
+
cdef bint owner
|
|
68
|
+
|
|
69
|
+
@staticmethod
|
|
70
|
+
cdef InternStringPool c_from_header(const istr_map* header, bint owner=*)
|
|
71
|
+
|
|
72
|
+
cpdef InternString istr(self, str string)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
cdef class IstrTestToolkit:
|
|
76
|
+
cdef char* buf
|
|
77
|
+
cdef readonly size_t buf_size
|
|
78
|
+
cdef size_t* seg_offsets
|
|
79
|
+
cdef size_t* seg_lengths
|
|
80
|
+
cdef const char** c_keys
|
|
81
|
+
cdef size_t* c_key_lens
|
|
82
|
+
cdef readonly size_t n_seg
|
|
83
|
+
cdef readonly size_t max_seg_len
|
|
84
|
+
cdef readonly size_t n_iters
|
|
85
|
+
cdef readonly size_t n_unique
|
|
86
|
+
|
|
87
|
+
cdef size_t* shuffle_indices
|
|
88
|
+
cdef readonly size_t n_ops
|
|
89
|
+
|
|
90
|
+
cdef readonly InternStringPool pool
|
|
91
|
+
cdef list py_strings
|
|
92
|
+
cdef list py_bytes_list
|
|
93
|
+
|
|
94
|
+
cdef inline void c_gen_buf(self)
|
|
95
|
+
cdef inline void c_gen_segments(self)
|
|
96
|
+
cdef inline void c_gen_shuffle(self)
|
|
97
|
+
cdef inline void c_gen_miss_pattern(self, double miss_rate)
|
|
98
|
+
cdef inline void c_prepare_py_objects(self)
|
|
99
|
+
cdef inline void c_prepare_istr_pool(self)
|
|
100
|
+
|
|
101
|
+
cpdef double istr_hash_routine(self)
|
|
102
|
+
cpdef double istr_intern_routine(self)
|
|
103
|
+
cpdef double istr_intern_synced_routine(self)
|
|
104
|
+
cpdef double istr_lookup_routine(self)
|
|
105
|
+
cpdef double istr_lookup_synced_routine(self)
|
|
106
|
+
cpdef double istr_limited_pool_routine(self)
|
|
107
|
+
cpdef double istr_limited_pool_synced_routine(self)
|
|
108
|
+
cpdef double istr_miss_rate_routine(self, double miss_rate)
|
|
109
|
+
cpdef double py_unicode_miss_rate_routine(self, double miss_rate)
|
|
110
|
+
cpdef double istr_eq_routine(self)
|
|
111
|
+
cpdef double py_unicode_routine(self)
|
|
112
|
+
cpdef double py_unicode_limited_routine(self)
|
|
113
|
+
cpdef double py_hash_routine(self)
|
|
114
|
+
cpdef double py_eq_routine(self)
|
|
115
|
+
cpdef dict run_test(self)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
cdef istr_map* C_POOL
|
|
119
|
+
cdef InternStringPool POOL
|
|
120
|
+
cdef istr_map* C_INTRA_POOL
|
|
121
|
+
cdef InternStringPool INTRA_POOL
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
from collections.abc import Generator
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class InternString:
|
|
6
|
+
"""A view into an interned string entry owned by an ``InternStringPool``.
|
|
7
|
+
|
|
8
|
+
Each ``InternString`` holds a reference to its parent pool and a
|
|
9
|
+
pointer to the underlying C string buffer. Two ``InternString``
|
|
10
|
+
instances compare equal when their string values are equal, even if
|
|
11
|
+
they belong to different pools.
|
|
12
|
+
|
|
13
|
+
Attributes:
|
|
14
|
+
pool: The ``InternStringPool`` that owns this interned entry.
|
|
15
|
+
hash_value: The raw 64-bit FNV-1a hash stored for this key.
|
|
16
|
+
address: Hex string of the underlying C pointer, or ``None``.
|
|
17
|
+
string: The Python ``str`` content of the interned entry.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
pool: InternStringPool
|
|
21
|
+
"""The ``InternStringPool`` that owns this interned entry."""
|
|
22
|
+
|
|
23
|
+
hash_value: int
|
|
24
|
+
"""The raw 64-bit FNV-1a hash stored for this key (read-only)."""
|
|
25
|
+
|
|
26
|
+
address: str | None
|
|
27
|
+
"""Hex string of the underlying C pointer (e.g. ``'0x7f...'``), or ``None`` if uninitialized."""
|
|
28
|
+
|
|
29
|
+
string: str
|
|
30
|
+
"""The Python ``str`` content of this interned entry.
|
|
31
|
+
|
|
32
|
+
Raises:
|
|
33
|
+
RuntimeError: If the view is uninitialized.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def __gt__(self, other: object) -> bool:
|
|
37
|
+
"""Return ``True`` if this interned string is greater than *other*.
|
|
38
|
+
|
|
39
|
+
Supports comparison with another ``InternString`` or a plain
|
|
40
|
+
Python ``str``.
|
|
41
|
+
"""
|
|
42
|
+
...
|
|
43
|
+
|
|
44
|
+
def __eq__(self, other: object) -> bool:
|
|
45
|
+
"""Return ``True`` if *other* has the same string value.
|
|
46
|
+
|
|
47
|
+
Supports comparison with another ``InternString`` or a plain
|
|
48
|
+
Python ``str``. Cross-pool comparisons compare by value.
|
|
49
|
+
"""
|
|
50
|
+
...
|
|
51
|
+
|
|
52
|
+
def __hash__(self) -> int:
|
|
53
|
+
"""Return the cached hash value truncated to signed 64-bit range.
|
|
54
|
+
|
|
55
|
+
The underlying hash is a full 64-bit FNV-1a; this accessor
|
|
56
|
+
masks to the low 63 bits for compatibility with Python's
|
|
57
|
+
``Py_hash_t`` slot. Suitable for use in dicts and sets.
|
|
58
|
+
"""
|
|
59
|
+
...
|
|
60
|
+
|
|
61
|
+
def __repr__(self) -> str:
|
|
62
|
+
"""Return a short representation showing the class name and string value.
|
|
63
|
+
|
|
64
|
+
Uninitialized instances show ``'(uninitialized)'``.
|
|
65
|
+
"""
|
|
66
|
+
...
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class InternStringPool:
|
|
70
|
+
"""A thread-safe hash map that interns (deduplicates) strings.
|
|
71
|
+
|
|
72
|
+
Strings are stored as NUL-terminated UTF-8 in memory backed by the
|
|
73
|
+
module's allocator protocol. Each unique key is stored exactly once;
|
|
74
|
+
subsequent ``istr()`` calls return the same ``InternString`` view.
|
|
75
|
+
|
|
76
|
+
``InternStringPool()`` creates a pool with the default allocator
|
|
77
|
+
(SHM-backed, locked, freelist-enabled). Module-level singletons
|
|
78
|
+
``POOL`` (SHM) and ``INTRA_POOL`` (heap) are also available.
|
|
79
|
+
|
|
80
|
+
Attributes:
|
|
81
|
+
size: Number of unique interned strings (same as ``len(pool)``).
|
|
82
|
+
address: Hex string of the underlying C ``istr_map`` pointer, or ``None``.
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
size: int
|
|
86
|
+
"""The number of unique interned strings in the pool."""
|
|
87
|
+
|
|
88
|
+
address: str | None
|
|
89
|
+
"""Hex string of the underlying C ``istr_map`` pointer, or ``None``."""
|
|
90
|
+
|
|
91
|
+
def __init__(self) -> None:
|
|
92
|
+
"""Create an empty pool backed by the default allocator.
|
|
93
|
+
|
|
94
|
+
The default allocator is SHM-backed with locking and freelist
|
|
95
|
+
enabled, suitable for cross-process sharing.
|
|
96
|
+
"""
|
|
97
|
+
...
|
|
98
|
+
|
|
99
|
+
def __len__(self) -> int:
|
|
100
|
+
"""Return the number of unique interned strings (same as :attr:`size`)."""
|
|
101
|
+
...
|
|
102
|
+
|
|
103
|
+
def __getitem__(self, key: str) -> InternString:
|
|
104
|
+
"""Return an ``InternString`` view for *key*.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
key: The string to look up.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
An ``InternString`` wrapping the interned entry.
|
|
111
|
+
|
|
112
|
+
Raises:
|
|
113
|
+
KeyError: If *key* has not been interned in this pool.
|
|
114
|
+
"""
|
|
115
|
+
...
|
|
116
|
+
|
|
117
|
+
def __contains__(self, key: str) -> bool:
|
|
118
|
+
"""Return ``True`` if *key* is interned in this pool.
|
|
119
|
+
|
|
120
|
+
Delegates to ``c_istr_map_lookup_synced`` — a pure read-only
|
|
121
|
+
lookup with no side effects. Returns ``False`` for missing
|
|
122
|
+
keys instead of raising :exc:`KeyError` like :meth:`__getitem__`
|
|
123
|
+
does.
|
|
124
|
+
"""
|
|
125
|
+
...
|
|
126
|
+
|
|
127
|
+
def istr(self, string: str) -> InternString:
|
|
128
|
+
"""Intern (or look up) *string* and return an ``InternString`` view.
|
|
129
|
+
|
|
130
|
+
If *string* is already in the pool the existing entry is
|
|
131
|
+
returned; otherwise it is interned (copied into pool memory).
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
string: The Python ``str`` to intern.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
An ``InternString`` wrapping the interned entry.
|
|
138
|
+
|
|
139
|
+
Raises:
|
|
140
|
+
MemoryError: If allocation fails.
|
|
141
|
+
"""
|
|
142
|
+
...
|
|
143
|
+
|
|
144
|
+
def internalized(self) -> Generator[InternString, None, None]:
|
|
145
|
+
"""Yield all interned entries as ``InternString`` views.
|
|
146
|
+
|
|
147
|
+
Iteration order is reverse insertion order (LIFO linked list).
|
|
148
|
+
Re-interning an existing key does not change its position.
|
|
149
|
+
|
|
150
|
+
Yields:
|
|
151
|
+
``InternString`` instances for every entry in the pool.
|
|
152
|
+
"""
|
|
153
|
+
...
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class IstrTestToolkit:
|
|
157
|
+
"""Performance benchmark toolkit for ``InternString`` vs Python ``str``.
|
|
158
|
+
|
|
159
|
+
Generates a large shared character buffer, segments it into
|
|
160
|
+
random-length strings, then benchmarks C-level hash / intern /
|
|
161
|
+
lookup / equality against equivalent Python ``str`` operations.
|
|
162
|
+
|
|
163
|
+
Attributes:
|
|
164
|
+
buf_size: Size of the character buffer in bytes.
|
|
165
|
+
n_seg: Number of random segments generated.
|
|
166
|
+
max_seg_len: Maximum length of each random segment in bytes.
|
|
167
|
+
n_iters: Number of benchmark iterations.
|
|
168
|
+
n_unique: Number of unique strings in the limited-pool subset.
|
|
169
|
+
n_ops: Number of operations per limited-pool iteration.
|
|
170
|
+
pool: An ``InternStringPool`` pre-populated with all segments.
|
|
171
|
+
"""
|
|
172
|
+
|
|
173
|
+
buf_size: int
|
|
174
|
+
"""Size of the character buffer in bytes."""
|
|
175
|
+
|
|
176
|
+
n_seg: int
|
|
177
|
+
"""Number of random segments generated."""
|
|
178
|
+
|
|
179
|
+
max_seg_len: int
|
|
180
|
+
"""Maximum length of each random segment in bytes."""
|
|
181
|
+
|
|
182
|
+
n_iters: int
|
|
183
|
+
"""Number of benchmark iterations per routine."""
|
|
184
|
+
|
|
185
|
+
n_unique: int
|
|
186
|
+
"""Number of unique strings in the limited-pool subset."""
|
|
187
|
+
|
|
188
|
+
n_ops: int
|
|
189
|
+
"""Number of operations per limited-pool iteration."""
|
|
190
|
+
|
|
191
|
+
pool: InternStringPool
|
|
192
|
+
"""An ``InternStringPool`` pre-populated with all segments for warm-up."""
|
|
193
|
+
|
|
194
|
+
def __init__(
|
|
195
|
+
self,
|
|
196
|
+
buf_size: int = 2**30,
|
|
197
|
+
n_seg: int = 100_000,
|
|
198
|
+
max_seg_len: int = 64,
|
|
199
|
+
n_iters: int = 10,
|
|
200
|
+
n_unique: int = 0,
|
|
201
|
+
n_ops: int = 0,
|
|
202
|
+
) -> None:
|
|
203
|
+
"""Create a benchmark toolkit with random reproducible data.
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
buf_size: Size of the character buffer in bytes (default 1 GiB).
|
|
207
|
+
n_seg: Number of random segments to generate (default 100 000).
|
|
208
|
+
max_seg_len: Maximum segment length in bytes (default 64).
|
|
209
|
+
n_iters: Number of benchmark iterations (default 10).
|
|
210
|
+
n_unique: Unique strings for limited-pool benchmarks
|
|
211
|
+
(default ``max(n_seg // 10, 1)``).
|
|
212
|
+
n_ops: Operations per limited-pool iteration (default *n_seg*).
|
|
213
|
+
|
|
214
|
+
Raises:
|
|
215
|
+
ValueError: If parameters are inconsistent.
|
|
216
|
+
MemoryError: If buffer or segment array allocation fails.
|
|
217
|
+
"""
|
|
218
|
+
...
|
|
219
|
+
|
|
220
|
+
def istr_hash_routine(self) -> float:
|
|
221
|
+
"""Benchmark FNV-1a hash at C level (no allocation).
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
Total elapsed time in seconds across all iterations.
|
|
225
|
+
"""
|
|
226
|
+
...
|
|
227
|
+
|
|
228
|
+
def istr_intern_routine(self) -> float:
|
|
229
|
+
"""Benchmark ``c_istr`` intern (all-miss, unlocked).
|
|
230
|
+
|
|
231
|
+
Creates a fresh pool per iteration.
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
Total elapsed time in seconds.
|
|
235
|
+
"""
|
|
236
|
+
...
|
|
237
|
+
|
|
238
|
+
def istr_intern_synced_routine(self) -> float:
|
|
239
|
+
"""Benchmark ``c_istr_synced`` intern (all-miss, locked).
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
Total elapsed time in seconds.
|
|
243
|
+
"""
|
|
244
|
+
...
|
|
245
|
+
|
|
246
|
+
def istr_lookup_routine(self) -> float:
|
|
247
|
+
"""Benchmark ``c_istr_map_lookup`` (all-hits, unlocked).
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
Total elapsed time in seconds.
|
|
251
|
+
"""
|
|
252
|
+
...
|
|
253
|
+
|
|
254
|
+
def istr_lookup_synced_routine(self) -> float:
|
|
255
|
+
"""Benchmark ``c_istr_map_lookup_synced`` (all-hits, locked).
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
Total elapsed time in seconds.
|
|
259
|
+
"""
|
|
260
|
+
...
|
|
261
|
+
|
|
262
|
+
def istr_eq_routine(self) -> float:
|
|
263
|
+
"""Benchmark ``InternString`` Python-level equality.
|
|
264
|
+
|
|
265
|
+
Returns:
|
|
266
|
+
Total elapsed time in seconds.
|
|
267
|
+
"""
|
|
268
|
+
...
|
|
269
|
+
|
|
270
|
+
def py_unicode_routine(self) -> float:
|
|
271
|
+
"""Benchmark Python ``str`` creation from raw bytes.
|
|
272
|
+
|
|
273
|
+
Returns:
|
|
274
|
+
Total elapsed time in seconds.
|
|
275
|
+
"""
|
|
276
|
+
...
|
|
277
|
+
|
|
278
|
+
def py_hash_routine(self) -> float:
|
|
279
|
+
"""Benchmark Python ``hash()`` on all segments.
|
|
280
|
+
|
|
281
|
+
Returns:
|
|
282
|
+
Total elapsed time in seconds.
|
|
283
|
+
"""
|
|
284
|
+
...
|
|
285
|
+
|
|
286
|
+
def py_eq_routine(self) -> float:
|
|
287
|
+
"""Benchmark Python ``str`` equality.
|
|
288
|
+
|
|
289
|
+
Returns:
|
|
290
|
+
Total elapsed time in seconds.
|
|
291
|
+
"""
|
|
292
|
+
...
|
|
293
|
+
|
|
294
|
+
def istr_limited_pool_routine(self) -> float:
|
|
295
|
+
"""Benchmark intern with limited unique pool (hit-heavy, unlocked).
|
|
296
|
+
|
|
297
|
+
Each iteration picks *n_ops* random strings (with replacement)
|
|
298
|
+
from *n_unique* segments. Most operations are hits.
|
|
299
|
+
|
|
300
|
+
Returns:
|
|
301
|
+
Total elapsed time in seconds.
|
|
302
|
+
"""
|
|
303
|
+
...
|
|
304
|
+
|
|
305
|
+
def istr_limited_pool_synced_routine(self) -> float:
|
|
306
|
+
"""Same as :meth:`istr_limited_pool_routine` but locked.
|
|
307
|
+
|
|
308
|
+
Returns:
|
|
309
|
+
Total elapsed time in seconds.
|
|
310
|
+
"""
|
|
311
|
+
...
|
|
312
|
+
|
|
313
|
+
def py_unicode_limited_routine(self) -> float:
|
|
314
|
+
"""Benchmark Python ``str`` creation from limited-pool picks.
|
|
315
|
+
|
|
316
|
+
Returns:
|
|
317
|
+
Total elapsed time in seconds.
|
|
318
|
+
"""
|
|
319
|
+
...
|
|
320
|
+
|
|
321
|
+
def istr_miss_rate_routine(self, miss_rate: float) -> float:
|
|
322
|
+
"""Benchmark intern with a controlled miss rate (unlocked).
|
|
323
|
+
|
|
324
|
+
Args:
|
|
325
|
+
miss_rate: Fraction of operations that are misses, in (0, 1].
|
|
326
|
+
e.g. 0.001 → 1/1K, 0.0001 → 1/10K.
|
|
327
|
+
|
|
328
|
+
Returns:
|
|
329
|
+
Total elapsed time in seconds.
|
|
330
|
+
"""
|
|
331
|
+
...
|
|
332
|
+
|
|
333
|
+
def py_unicode_miss_rate_routine(self, miss_rate: float) -> float:
|
|
334
|
+
"""Benchmark Python ``str`` creation with a controlled miss rate.
|
|
335
|
+
|
|
336
|
+
Args:
|
|
337
|
+
miss_rate: Same semantics as :meth:`istr_miss_rate_routine`.
|
|
338
|
+
|
|
339
|
+
Returns:
|
|
340
|
+
Total elapsed time in seconds.
|
|
341
|
+
"""
|
|
342
|
+
...
|
|
343
|
+
|
|
344
|
+
def run_test(self) -> dict[str, Any]:
|
|
345
|
+
"""Run all benchmarks and return a dictionary of results.
|
|
346
|
+
|
|
347
|
+
Returns:
|
|
348
|
+
A dict with per-operation nanosecond averages
|
|
349
|
+
(``'_ns'`` keys) and raw timings in seconds (``'_s'`` keys),
|
|
350
|
+
plus metadata keys (``buf_size``, ``n_seg``, etc.).
|
|
351
|
+
"""
|
|
352
|
+
...
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
# Module-level singletons
|
|
356
|
+
|
|
357
|
+
POOL: InternStringPool
|
|
358
|
+
"""The global SHM-backed ``InternStringPool`` for cross-process sharing.
|
|
359
|
+
|
|
360
|
+
Backed by ``AP_SHM_ALLOCATOR`` — child processes inherit the shared
|
|
361
|
+
memory mapping and see all entries regardless of when they were interned.
|
|
362
|
+
"""
|
|
363
|
+
|
|
364
|
+
INTRA_POOL: InternStringPool
|
|
365
|
+
"""The global heap-backed ``InternStringPool`` for intra-process use.
|
|
366
|
+
|
|
367
|
+
Backed by ``AP_HEAP_ALLOCATOR``. After ``fork()`` the child sees a
|
|
368
|
+
COW copy of pre-fork entries but post-fork insertions are isolated to
|
|
369
|
+
each process.
|
|
370
|
+
"""
|
|
371
|
+
|
|
372
|
+
C_POOL: int
|
|
373
|
+
"""Raw pointer (``uintptr_t``) to the C ``istr_map`` backing ``POOL``."""
|
|
374
|
+
|
|
375
|
+
C_INTRA_POOL: int
|
|
376
|
+
"""Raw pointer (``uintptr_t``) to the C ``istr_map`` backing ``INTRA_POOL``."""
|