Skip to content
Snippets Groups Projects
Commit 8a8e4a42d063 authored by ijl's avatar ijl
Browse files

Reduce work in cache

parent bc06ded407d4
No related branches found
No related tags found
No related merge requests found
......@@ -2,5 +2,5 @@
# It is not intended for manual editing.
[[package]]
name = "arrayvec"
version = "0.5.1"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
......@@ -6,5 +6,5 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "associative-cache"
......@@ -124,7 +124,7 @@
"serde",
"serde_json",
"smallvec",
"wyhash",
"wy",
]
[[package]]
......@@ -174,12 +174,6 @@
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
......@@ -248,6 +242,6 @@
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "wyhash"
version = "0.4.1"
name = "wy"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
......@@ -253,5 +247,2 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fe26121db27575e4fb30ceded9806fbfe0edb489f170a17506d9ad0b1aca41c"
dependencies = [
"rand_core",
]
checksum = "f3dede6c845dff0b268e7b0c12bc92c97d1e9aafdce335e8e1d0eadbd52c7357"
......@@ -60,7 +60,7 @@
serde = { version = "1", default_features = false }
serde_json = { path = "./json", default_features = false, features = ["std"] }
smallvec = { version = "1", default_features = false, features = ["const_generics", "union", "specialization", "write"] }
wyhash = { version = "0.4" }
wy = { version = "1" }
[target.'cfg(not(any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "i686", target_arch = "armv7")))'.dependencies]
encoding_rs = { path = "./encoding_rs", default_features = false }
......
......@@ -590,7 +590,7 @@
orjson maintains a cache of map keys for the duration of the process. This
causes a net reduction in memory usage by avoiding duplicate strings. The
keys must be at most 64 chars to be cached and 512 entries are stored.
keys must be at most 64 bytes to be cached and 512 entries are stored.
It raises `JSONDecodeError` if given an invalid type or invalid
JSON. This includes if the input contains `NaN`, `Infinity`, or `-Infinity`,
......
......@@ -5,6 +5,6 @@
use once_cell::unsync::OnceCell;
use std::os::raw::c_void;
#[derive(Clone)]
#[repr(transparent)]
pub struct CachedKey {
ptr: *mut c_void,
......@@ -9,9 +9,8 @@
pub struct CachedKey {
ptr: *mut c_void,
hash: pyo3::ffi::Py_hash_t,
}
unsafe impl Send for CachedKey {}
unsafe impl Sync for CachedKey {}
impl CachedKey {
......@@ -12,9 +11,9 @@
}
unsafe impl Send for CachedKey {}
unsafe impl Sync for CachedKey {}
impl CachedKey {
pub fn new(ptr: *mut pyo3::ffi::PyObject, hash: pyo3::ffi::Py_hash_t) -> CachedKey {
pub fn new(ptr: *mut pyo3::ffi::PyObject) -> CachedKey {
CachedKey {
ptr: ptr as *mut c_void,
......@@ -19,6 +18,5 @@
CachedKey {
ptr: ptr as *mut c_void,
hash: hash,
}
}
......@@ -22,6 +20,6 @@
}
}
pub fn get(&mut self) -> (*mut pyo3::ffi::PyObject, pyo3::ffi::Py_hash_t) {
pub fn get(&mut self) -> *mut pyo3::ffi::PyObject {
let ptr = self.ptr as *mut pyo3::ffi::PyObject;
ffi!(Py_INCREF(ptr));
......@@ -26,6 +24,6 @@
let ptr = self.ptr as *mut pyo3::ffi::PyObject;
ffi!(Py_INCREF(ptr));
(ptr, self.hash)
ptr
}
}
......@@ -36,6 +34,6 @@
}
pub type KeyMap =
AssociativeCache<u64, CachedKey, Capacity512, HashDirectMapped, RoundRobinReplacement>;
AssociativeCache<u32, CachedKey, Capacity512, HashDirectMapped, RoundRobinReplacement>;
pub static mut KEY_MAP: OnceCell<KeyMap> = OnceCell::new();
......@@ -10,7 +10,7 @@
use std::borrow::Cow;
use std::fmt;
use std::ptr::NonNull;
use wyhash::wyhash;
use wy::hash32;
pub fn deserialize(
ptr: *mut pyo3::ffi::PyObject,
......@@ -167,4 +167,5 @@
while let Some(key) = map.next_key::<Cow<str>>()? {
let pykey: *mut pyo3::ffi::PyObject;
let pyhash: pyo3::ffi::Py_hash_t;
let value = map.next_value_seed(self)?;
if likely!(key.len() <= 64) {
......@@ -170,5 +171,5 @@
if likely!(key.len() <= 64) {
let hash = unsafe { wyhash(key.as_bytes(), HASH_SEED) };
let hash = unsafe { hash32(key.as_bytes(), HASH_SEED) };
{
let map = unsafe {
KEY_MAP
......@@ -179,6 +180,7 @@
|| hash,
|| {
let pyob = unicode_from_str(&key);
CachedKey::new(pyob, hash_str(pyob))
hash_str(pyob);
CachedKey::new(pyob)
},
);
......@@ -183,10 +185,9 @@
},
);
let tmp = entry.get();
pykey = tmp.0;
pyhash = tmp.1;
pykey = entry.get();
pyhash = unsafe { (*pykey.cast::<PyASCIIObject>()).hash }
}
} else {
pykey = unicode_from_str(&key);
pyhash = hash_str(pykey);
}
......@@ -188,9 +189,8 @@
}
} else {
pykey = unicode_from_str(&key);
pyhash = hash_str(pykey);
}
let value = map.next_value_seed(self)?;
let _ = ffi!(_PyDict_SetItem_KnownHash(
dict_ptr,
pykey,
......
......@@ -17,7 +17,7 @@
pub uint32: *mut PyTypeObject,
pub uint8: *mut PyTypeObject,
}
pub static mut HASH_SEED: u64 = 0;
pub static mut HASH_SEED: u32 = 0;
pub static mut NONE: *mut PyObject = 0 as *mut PyObject;
pub static mut TRUE: *mut PyObject = 0 as *mut PyObject;
......@@ -102,7 +102,7 @@
ARRAY_STRUCT_STR =
pyo3::ffi::PyUnicode_InternFromString("__array_struct__\0".as_ptr() as *const c_char);
VALUE_STR = pyo3::ffi::PyUnicode_InternFromString("value\0".as_ptr() as *const c_char);
HASH_SEED = (VALUE_STR as u64).wrapping_mul(DICT_TYPE as u64);
HASH_SEED = ((VALUE_STR as u64).wrapping_mul(DICT_TYPE as u64)) as u32;
DEFAULT = PyUnicode_InternFromString("default\0".as_ptr() as *const c_char);
OPTION = PyUnicode_InternFromString("option\0".as_ptr() as *const c_char);
JsonEncodeError = pyo3::ffi::PyExc_TypeError;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment