通过Cython管理calloc/free调用
项目描述
cymem: 一个Cython内存助手
cymem为Cython提供两个小的内存管理助手。它们可以轻松地将内存与Python对象的生存周期绑定,以便在对象被垃圾回收时释放内存。
概述
最有用的是cymem.Pool
,它是对calloc函数的轻量级包装
from cymem.cymem cimport Pool
cdef Pool mem = Pool()
data1 = <int*>mem.alloc(10, sizeof(int))
data2 = <float*>mem.alloc(12, sizeof(float))
《Pool》对象在内部保存内存地址,并在对象被垃圾回收时释放它们。通常,您会将《Pool》附加到某些cdef'd类。这对于深度嵌套的结构特别有用,这些结构具有复杂的初始化函数。只需将《Pool》对象传递给初始化函数,您就无需担心释放您的结构——所有对《Pool.alloc》的调用都会在《Pool》到期时自动释放。
安装
通过pip安装,并需要Cython。在安装之前,请确保您的《pip》、《setuptools》和《wheel》都是最新的。
pip install -U pip setuptools wheel
pip install cymem
示例用例:结构数组
假设我们想要一个稀疏矩阵序列。我们需要快速访问,而Python列表的性能不够好。因此,我们想要一个C数组或C++向量,这意味着稀疏矩阵必须是一个C级别的结构——它不能是一个Python类。我们可以在Cython中轻松地编写这个
"""Example without Cymem
To use an array of structs, we must carefully walk the data structure when
we deallocate it.
"""
from libc.stdlib cimport calloc, free
cdef struct SparseRow:
size_t length
size_t* indices
double* values
cdef struct SparseMatrix:
size_t length
SparseRow* rows
cdef class MatrixArray:
cdef size_t length
cdef SparseMatrix** matrices
def __cinit__(self, list py_matrices):
self.length = 0
self.matrices = NULL
def __init__(self, list py_matrices):
self.length = len(py_matrices)
self.matrices = <SparseMatrix**>calloc(len(py_matrices), sizeof(SparseMatrix*))
for i, py_matrix in enumerate(py_matrices):
self.matrices[i] = sparse_matrix_init(py_matrix)
def __dealloc__(self):
for i in range(self.length):
sparse_matrix_free(self.matrices[i])
free(self.matrices)
cdef SparseMatrix* sparse_matrix_init(list py_matrix) except NULL:
sm = <SparseMatrix*>calloc(1, sizeof(SparseMatrix))
sm.length = len(py_matrix)
sm.rows = <SparseRow*>calloc(sm.length, sizeof(SparseRow))
cdef size_t i, j
cdef dict py_row
cdef size_t idx
cdef double value
for i, py_row in enumerate(py_matrix):
sm.rows[i].length = len(py_row)
sm.rows[i].indices = <size_t*>calloc(sm.rows[i].length, sizeof(size_t))
sm.rows[i].values = <double*>calloc(sm.rows[i].length, sizeof(double))
for j, (idx, value) in enumerate(py_row.items()):
sm.rows[i].indices[j] = idx
sm.rows[i].values[j] = value
return sm
cdef void* sparse_matrix_free(SparseMatrix* sm) except *:
cdef size_t i
for i in range(sm.length):
free(sm.rows[i].indices)
free(sm.rows[i].values)
free(sm.rows)
free(sm)
我们尽可能地在一个低级别的Python ref-counted类中封装数据结构,考虑到我们的性能限制。这允许我们在Cython的特殊方法《__cinit__》和《__dealloc__》中分配和释放内存。
然而,在编写《__dealloc__》和《sparse_matrix_free》函数时,很容易出错,导致内存泄漏。cymem阻止您编写这些析构函数。相反,您应该这样编写
"""Example with Cymem.
Memory allocation is hidden behind the Pool class, which remembers the
addresses it gives out. When the Pool object is garbage collected, all of
its addresses are freed.
We don't need to write MatrixArray.__dealloc__ or sparse_matrix_free,
eliminating a common class of bugs.
"""
from cymem.cymem cimport Pool
cdef struct SparseRow:
size_t length
size_t* indices
double* values
cdef struct SparseMatrix:
size_t length
SparseRow* rows
cdef class MatrixArray:
cdef size_t length
cdef SparseMatrix** matrices
cdef Pool mem
def __cinit__(self, list py_matrices):
self.mem = None
self.length = 0
self.matrices = NULL
def __init__(self, list py_matrices):
self.mem = Pool()
self.length = len(py_matrices)
self.matrices = <SparseMatrix**>self.mem.alloc(self.length, sizeof(SparseMatrix*))
for i, py_matrix in enumerate(py_matrices):
self.matrices[i] = sparse_matrix_init(self.mem, py_matrix)
cdef SparseMatrix* sparse_matrix_init_cymem(Pool mem, list py_matrix) except NULL:
sm = <SparseMatrix*>mem.alloc(1, sizeof(SparseMatrix))
sm.length = len(py_matrix)
sm.rows = <SparseRow*>mem.alloc(sm.length, sizeof(SparseRow))
cdef size_t i, j
cdef dict py_row
cdef size_t idx
cdef double value
for i, py_row in enumerate(py_matrix):
sm.rows[i].length = len(py_row)
sm.rows[i].indices = <size_t*>mem.alloc(sm.rows[i].length, sizeof(size_t))
sm.rows[i].values = <double*>mem.alloc(sm.rows[i].length, sizeof(double))
for j, (idx, value) in enumerate(py_row.items()):
sm.rows[i].indices[j] = idx
sm.rows[i].values[j] = value
return sm
《Pool》类所做的一切只是记住它给出的地址。当《MatrixArray》对象被垃圾回收时,也会回收《Pool》对象,这会触发对《Pool.__dealloc__》的调用。然后,《Pool》会释放其所有的地址。这可以节省您回溯嵌套数据结构来释放它们,消除了常见错误类型。
自定义分配器
有时外部C库使用私有函数来分配和释放对象,但我们仍然希望有《Pool》的懒惰性。
from cymem.cymem cimport Pool, WrapMalloc, WrapFree
cdef Pool mem = Pool(WrapMalloc(priv_malloc), WrapFree(priv_free))
项目详情
下载文件
下载适合您平台的文件。如果您不确定该选择哪个,请了解更多关于安装包的信息。
源代码分发
构建分发
cymem-2.0.8.tar.gz 的哈希
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 8fb09d222e21dcf1c7e907dc85cf74501d4cea6c4ed4ac6c9e016f98fb59cbbf |
|
MD5 | 1cc1952c8af3a3a85b6b8054b74af7c5 |
|
BLAKE2b-256 | 3632f4a457fc6c160a9e72b15dab1ca14ca5c8869074638bca8bfc26120c04e9 |
哈希 对于 cymem-2.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 7bf49e3ea2c441f7b7848d5c61b50803e8cbd49541a70bb41ad22fce76d87603 |
|
MD5 | 59033bc48ba57647a962ef41671bf1a3 |
|
BLAKE2b-256 | 3b591cc0df0f8a5fb90412cfc7eb084ceeb079f4349232c422e10e502eb255c3 |
哈希 对于 cymem-2.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | a2cc38930ff5409f8d61f69a01e39ecb185c175785a1c9bec13bcd3ac8a614ba |
|
MD5 | bb4ba147a0774f9acccbfa907ac3a45d |
|
BLAKE2b-256 | 8a7770f8b77c4db30e5765092033e283aadd51ad78364f10cd2d331a1f158fcb |
哈希 对于 cymem-2.0.8-cp312-cp312-macosx_10_9_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | cb51fddf1b920abb1f2742d1d385469bc7b4b8083e1cfa60255e19bc0900ccb5 |
|
MD5 | 210ecdd8b9743c2970745c64ffc2adf9 |
|
BLAKE2b-256 | a3f8030ee2fc2665f7d2e62079299e593a79a661b8a32f69653fee6cc0cd2f30 |
哈希 对于 cymem-2.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 42c993589d1811ec665d37437d5677b8757f53afadd927bf8516ac8ce2d3a50c |
|
MD5 | bcb6dd11cba74aab3e6e6ffa34b2f166 |
|
BLAKE2b-256 | e5bc761acaf88b1fa69a6b75b55c24fbd8b47dab1a3c414d9512e907a646a048 |
哈希 对于 cymem-2.0.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 4ac218cf8a43a761dc6b2f14ae8d183aca2bbb85b60fe316fd6613693b2a7914 |
|
MD5 | 2e1c0ce4ca98d2ef4c1150deda79ba4c |
|
BLAKE2b-256 | bb3b3d6b284c82be7571c0a67b11edce486f404971b4ec849fac4a679f85f93a |
哈希 对于 cymem-2.0.8-cp311-cp311-macosx_10_9_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 6b84b780d52cb2db53d4494fe0083c4c5ee1f7b5380ceaea5b824569009ee5bd |
|
MD5 | 2a67cf98d592319204e4f58f0e41038d |
|
BLAKE2b-256 | 201f2ae07056430a0276e0cbd765652db82ea153c5fb2a3d753fbffd553827d5 |
哈希 对于 cymem-2.0.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | e8260445652ae5ab19fff6851f32969a7b774f309162e83367dd0f69aac5dbf7 |
|
MD5 | c66b229b680238bcd06f671f59585294 |
|
BLAKE2b-256 | e9133bed1a1d1cce7937eb797d760c0cca973dbdc1891ad7e2f066ae418fd697 |
哈希 对于 cymem-2.0.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 29a551eda23eebd6d076b855f77a5ed14a1d1cae5946f7b3cb5de502e21b39b0 |
|
MD5 | 5b09218013c22d6fefa2de9552bd7e0b |
|
BLAKE2b-256 | 42f0a5cfe24f98b9fa1c6552e7d6f3e67db3a2bd9d68cc3946651cd53513f588 |
哈希值 用于 cymem-2.0.8-cp310-cp310-macosx_11_0_arm64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | bd33da892fb560ba85ea14b1528c381ff474048e861accc3366c8b491035a378 |
|
MD5 | 81c34a0920aacc716186f34811b08049 |
|
BLAKE2b-256 | 83bb21dcb7cb06c97fd99019369071f0b9ad544c3db68343abbceb283e8a5223 |
哈希值 用于 cymem-2.0.8-cp310-cp310-macosx_10_9_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 77b5d3a73c41a394efd5913ab7e48512054cd2dabb9582d489535456641c7666 |
|
MD5 | 6993a3b361cafd2c2d80455f99d7f6e7 |
|
BLAKE2b-256 | 06e80ab9faadd0911307c4158cc52abcaae6141283abb17275326b4d3b99089f |
哈希值 用于 cymem-2.0.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | e4e57bee56d35b90fc2cba93e75b2ce76feaca05251936e28a96cf812a1f5dda |
|
MD5 | ce9b44a16d9a6fe24e4b995677248a11 |
|
BLAKE2b-256 | 2b9e18c6e7ac58ac84a02d3db0f43771515cdc4621b2e8e7062939dd6adef0df |
哈希值 用于 cymem-2.0.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 7372e2820fa66fd47d3b135f3eb574ab015f90780c3a21cfd4809b54f23a4723 |
|
MD5 | 14e9ee5ba2556637e683e68470e2e2a8 |
|
BLAKE2b-256 | be04d37d326234dcf51596613973c6fe7da6a309e49fe08578f266b8e84d641e |
哈希值 用于 cymem-2.0.8-cp39-cp39-macosx_10_9_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | b896c83c08dadafe8102a521f83b7369a9c5cc3e7768eca35875764f56703f4c |
|
MD5 | 0fa17238544ed92dbc750c244d69bc64 |
|
BLAKE2b-256 | 0269ae03a9b809b1fda0f66d7f17ac0042fb5f7c70950884dffc986b112267ef |
哈希值 用于 cymem-2.0.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 84f8c58cde71b8fc7024883031a4eec66c0a9a4d36b7850c3065493652695156 |
|
MD5 | da7dfa7bfb9141dd48e15ccfb48dfd68 |
|
BLAKE2b-256 | 5f70b9945a7918d467c6c7112f6e20176d4f41b89d7ba0b590015b4cb62fb23d |
哈希值 用于 cymem-2.0.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 8e370dd54359101b125bfb191aca0542718077b4edb90ccccba1a28116640fed |
|
MD5 | 119ef564be459ed680cfe12aaa832cf4 |
|
BLAKE2b-256 | 50e0c118049bb79a024b17a9791f17d60fa50782414c1f55ea388cfee3c8ac5c |
哈希值 用于 cymem-2.0.8-cp38-cp38-macosx_10_9_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 1e593cd57e2e19eb50c7ddaf7e230b73c890227834425b9dadcd4a86834ef2ab |
|
MD5 | 2e595cdc19cec0c33d30b135feef5a50 |
|
BLAKE2b-256 | 56e0d3b5727fd7650bc9617edd8dd982405adb44a012e19890972608ff53afa0 |
哈希值 用于 cymem-2.0.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | e6b83a5972a64f62796118da79dfeed71f4e1e770b2b7455e889c909504c2358 |
|
MD5 | 1a4500900b857c2327bd921968e43556 |
|
BLAKE2b-256 | 1591ff540730f341dee2ad7fade35e13ce0f9ad4d4e5b20855a074b9a0c5126e |
哈希值 用于 cymem-2.0.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 6ce641f7ba0489bd1b42a4335a36f38c8507daffc29a512681afaba94a0257d2 |
|
MD5 | ba8400a23d2ba30cd68f808943ad4e6a |
|
BLAKE2b-256 | 2da9370c3ace4d318ed556490c5f91e6e896007e78fe7ac37086d50777a56223 |
哈希值 用于 cymem-2.0.8-cp37-cp37m-macosx_10_9_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | b9c05db55ea338648f8e5f51dd596568c7f62c5ae32bf3fa5b1460117910ebae |
|
MD5 | bb9922a327041f8e28375a7248b1331a |
|
BLAKE2b-256 | 2a00e900492172c167e06ecd3a0aabf9dc740d6d5620a535fa2df3a6c75fa1e5 |
哈希值 用于 cymem-2.0.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 17cd2c2791c8f6b52f269a756ba7463f75bf7265785388a2592623b84bb02bf8 |
|
MD5 | 519f87da9e87c47612aa522638740197 |
|
BLAKE2b-256 | 2c01e86cfbb8606c23d67fab01ed668ef11b34cb53611192eb73235cb7868d8b |
哈希值 用于 cymem-2.0.8-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 167d8019db3b40308aabf8183fd3fbbc256323b645e0cbf2035301058c439cd0 |
|
MD5 | 8836bebe5b91b66210b13359d8453223 |
|
BLAKE2b-256 | 3a5dad5ebb3ac2a5d885ddf4e908a3dafe218295e6428d2dce1789eb061dc9df |