88# Avoid checking the name of type annotations at run time
99from __future__ import annotations
1010
11+ import contextlib
1112import copy
1213import ctypes
1314import ctypes .util
15+ import json
1416import math
1517import os
1618import pathlib
1719import pickle
1820import platform
1921import sys
2022from dataclasses import asdict
23+ from functools import lru_cache
2124from typing import TYPE_CHECKING
2225
2326import cpuinfo
@@ -1149,7 +1152,7 @@ def linux_cache_size(cache_level: int, default_size: int) -> int:
11491152 return cache_size
11501153
11511154
1152- def get_cpu_info ():
1155+ def _get_cpu_info ():
11531156 cpu_info = cpuinfo .get_cpu_info ()
11541157 # cpuinfo does not correctly retrieve the cache sizes for Apple Silicon, so do it manually
11551158 if platform .system () == "Darwin" :
@@ -1167,6 +1170,32 @@ def get_cpu_info():
11671170 return cpu_info
11681171
11691172
1173+ def write_cached_cpu_info (cpu_info_dict : dict [str , any ]) -> None :
1174+ with open (pathlib .Path .home () / ".blosc2-cpuinfo.json" , "w" ) as f :
1175+ json .dump (cpu_info_dict , f , indent = 4 )
1176+
1177+
1178+ def read_cached_cpu_info () -> dict :
1179+ try :
1180+ with open (pathlib .Path .home () / ".blosc2-cpuinfo.json" ) as f :
1181+ return json .load (f )
1182+ except (FileNotFoundError , json .JSONDecodeError ):
1183+ return {}
1184+
1185+
1186+ @lru_cache (maxsize = 1 )
1187+ def get_cpu_info () -> dict :
1188+ cached_info = read_cached_cpu_info ()
1189+ if cached_info :
1190+ return cached_info
1191+
1192+ cpu_info_dict = _get_cpu_info ()
1193+ with contextlib .suppress (OSError ):
1194+ # In case cpu info cannot be stored, will need to be recomputed in the next process
1195+ write_cached_cpu_info (cpu_info_dict )
1196+ return cpu_info_dict
1197+
1198+
11701199def get_blocksize () -> int :
11711200 """Get the internal blocksize to be used during compression.
11721201
0 commit comments