Simple data structures accessible from both Python and C. Data in structures are stored as a primitive C types, so in C you can compute data without Python overhead.
Python code:
>>> import array >>> import itertools >>> import math >>> import random >>> from cdatastructs.hashmap import Int2Int >>> from my_c_extension import calculate_data # Create instance of the Int2Int - mapping from ID # to position in array >>> id2index = Int2Int() # Fill id2index, it is mapping, so you can use it same as dict >>> id2index[72351277] = 0 >>> id2index[98092127498] = 1 >>> id2index[126987499] = 2 >>> id2index[36] = 3 >>> id2index[980980] = 4 >>> len(id2index) 5 >>> id2index[980980] 4 >>> id2index.buffer_ptr 94691713534960 # Prepare two arrays with numbers for calculate and one array for results >>> a = array.array('d', (random.random() for _ in id2index)) >>> b = array.array('d', (random.random() for _ in id2index)) >>> results = array.array('d', (math.nan for _ in id2index)) # Calculate data for IDs 98092127498, 126987499 and 36 >>> ids = array.array('Q', [98092127498, 126987499, 36]) >>> calculate_data(id2index, ids, a, b, results) # Obtain result >>> results[id2index[72351277]] nan >>> results[id2index[98092127498]] 0.8163673050897404
C code:
#include <hashmap.h> static PyObject * my_c_extension_compute_data( PyObject *id2index, PyObject *args) { Int2IntHashTable_t *id2position; unsigned long long *ids; size_t *ids_count; double *a; double *b; double *res; // Parse args, obtain pointers to buffers and cast them to C types ... // Calculate data, there are only pure C types, no Python overhead for (size_t i=0; i<ids_count; ++i) { unsigned long long id = ids[i]; size_t *position; if (int2int_get(id2position, id, position) != 0) { goto error; } res[*position] = a[*position] + b[*position]; } ... Py_RETURN_NONE; error: ... return NULL; }
See demos/
for more examples and details.
3-clause BSD