Le vendredi 11 août 2023 à 20:19 -0400, Walter Lewis a écrit : > To be honest I don't know enough about C to know the performance of  > bytevector->pointer, so I was assuming Chickadee's approach was done for > a reason. Below is the definition of bytevector->pointer in libguile/foreign.c: SCM_DEFINE (scm_bytevector_to_pointer, "bytevector->pointer", 1, 1, 0, (SCM bv, SCM offset), "Return a pointer pointer aliasing the memory pointed to by\n" "@var{bv} or @var{offset} bytes after @var{bv} when @var{offset}\n" "is passed.") #define FUNC_NAME s_scm_bytevector_to_pointer { SCM ret; signed char *ptr; size_t boffset; SCM_VALIDATE_BYTEVECTOR (1, bv); ptr = SCM_BYTEVECTOR_CONTENTS (bv); if (SCM_UNBNDP (offset)) boffset = 0; else boffset = scm_to_unsigned_integer (offset, 0, SCM_BYTEVECTOR_LENGTH (bv) - 1); ret = scm_from_pointer (ptr + boffset, NULL); register_weak_reference (ret, bv); return ret; } #undef FUNC_NAME In plain English, this is basically just checking that the first argument is a bytevector and the second argument (if provided, defaults to 0) is an integer that is in bounds for the bytevector, then it calls SCM scm_from_pointer (void *ptr, scm_t_pointer_finalizer finalizer) { SCM ret; if (ptr == NULL && finalizer == NULL) ret = null_pointer; else { ret = scm_cell (scm_tc7_pointer, (scm_t_bits) ptr); if (finalizer) scm_i_set_finalizer (SCM2PTR (ret), pointer_finalizer_trampoline, finalizer); } return ret; } which just wraps the pointer into a (small and cheap) Guile object, and that's basically it. So, yet, it's very cheap. The only possible cost that I can see is memory and GC footprint, e.g., it's like creating many SRFI-111 boxes to the same object vs. one box, that kind of overhead. The objects themselves are very lightweight. You would really have to go out of your way and create an awful lot of them for this to make any difference.