@@ -177,13 +177,13 @@ class BatchArray:
177177 Maximum number of items stored in each internal variable-length block.
178178 The last block in a batch may contain fewer items than this cap. If not
179179 provided, a value is inferred from the first batch using the serialized
180- item sizes and the compression level. For ``clevel`` 1 through 5, the
181- heuristic targets the L1 data-cache size for faster scans and item
182- lookups. For ``clevel`` 6 through 8, it targets the L2 cache size for
183- larger blocks and better compression. At ``clevel`` 9, the whole batch
184- is kept as one block. Smaller blocks generally improve random access
185- and cache behavior , while larger blocks generally improve compression
186- ratio.
180+ item sizes and the compression level. The heuristic uses fixed byte
181+ budgets so that the layout (and hence the compression ratio) does not
182+ depend on the CPU it was created on: 1 MiB for ``clevel`` 1 through 3,
183+ 8 MiB for ``clevel`` 4 through 6, and 16 MiB for ``clevel`` 7 and 8.
184+ At ``clevel`` 9, the whole batch is kept as one block. Smaller blocks
185+ generally improve random access , while larger blocks generally improve
186+ compression ratio.
187187 serializer : {"msgpack", "arrow"}, optional
188188 Serializer used for batch payloads. ``"msgpack"`` is the default and is
189189 the general-purpose choice for Python items, including nested Blosc2
@@ -609,14 +609,19 @@ def _guess_blocksize(self, payload_sizes: list[int]) -> int:
609609 # too small for codecs like Zstd to exploit cross-row redundancy. Use larger
610610 # cache-budget tiers as clevel increases, while avoiding full L2 blocks at the
611611 # default clevel to keep random access reasonably granular.
612+ # UPDATE: to avoid cratio differences between CPUs, better use fixed budgets instead
613+ # of CPU cache sizes.
612614 if clevel == 9 :
613615 return len (payload_sizes )
614616 if 0 < clevel <= 3 :
615- budget = blosc2 .cpu_info .get ("l1_data_cache_size" )
617+ # budget = blosc2.cpu_info.get("l1_data_cache_size")
618+ budget = 2 ** 20 # 1 MB
616619 elif 3 < clevel <= 6 :
617- budget = blosc2 .cpu_info .get ("l2_cache_size" ) // 2
620+ # budget = blosc2.cpu_info.get("l2_cache_size") // 2
621+ budget = 2 ** 23 # 8 MB
618622 elif 6 < clevel < 9 :
619- budget = blosc2 .cpu_info .get ("l2_cache_size" )
623+ # budget = blosc2.cpu_info.get("l2_cache_size")
624+ budget = 2 ** 24 # 16 MB
620625 else :
621626 return len (payload_sizes )
622627 if not isinstance (budget , int ) or budget <= 0 :
0 commit comments