Rich-T-kid commented on PR #10262: URL: https://github.com/apache/arrow-rs/pull/10262#issuecomment-4889329978
Taking a second look at this, I'm a bit curious about the benchmark results, specifically in the cases of larger record batches, which this should ideally benefit the most. Let's say a 10MB record batch is split into 10 1MB chunks to be encoded into `flightData`. For chunks 1–9 (0-indexed), each one requests upfront 1MB due to the `reserve()`call., let's assume something like the standard library's `malloc`. [Mallocs man page](https://man7.org/linux/man-pages/man3/malloc.3.html): ``` malloc() allocates memory from the heap, and adjusts the size of the heap as required, using sbrk(2). When allocating blocks of memory larger than MMAP_THRESHOLD bytes, the glibc malloc() implementation allocates the memory as a private anonymous mapping using mmap(2). MMAP_THRESHOLD is 128 kB by default ``` [mallopt man page states](https://man7.org/linux/man-pages/man3/mallopt.3.html): ``` On the other hand, there are some disadvantages to the use of mmap(2): deallocated space is not placed on the free list for reuse by later allocations; ``` This means that after `FlightData` is dropped and `free(*ptr)` is called, the memory gets `munmap`'ed directly, without being returned to the allocator for reuse. I'm wondering if this might be what's causing the pre-allocation path to not show as strong a performance boost. 🤔 Even in the case where we don't pre-allocate the vectors, this happens anyway, since the vector will eventually grow to this size regardless, so the `munmap` cost is unavoidable either way. The only additional overhead I can think of with pre-allocation is that a single `mmap()` syscall is more expensive than the sequence of `sbrk()` calls used during incremental growth `(2, 4, 8, 16... up to 4KB, 2MB, etc.)`, since those smaller allocations stay under the mmap threshold. But even that difference washes out: in the non-pre-allocated case, the vector still eventually crosses the mmap threshold and triggers that same mmap-backed allocation once it grows large enough. `s: sbrk` `m: mmap` (pre-alloc) vec: ->[(1mb)] `m` (no-pre-alloc) vec: [2kb] -> [4kb] -> [8kb] ... [128kb] -> [256kb] -> [512kb] -> [1mb+] `s` `s` `s` `m` `m` `m` `m` in both cases drop doesnt return the buffer to the allocator and `munmap` is called. I may be missing something -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
