On 28 Apr 2017, at 03:09, Rick Mann via swift-users <swift-users@swift.org> 
wrote:

> Because this runs on iOS, I'd like to reduce the amount of time I hang on to 
> memory as much as possible (there's a lot of parallel processing happening in 
> our pipeline). I'd also like to avoid copying the data.
> 
> The resizing was the main reason I chose to use Data.

While I understand what you’re trying to achieve here you have to be careful 
that you don’t do a bunch of convoluted stuff only to find that, under the 
covers, the system is doing a copy for you anyway.

iOS’s memory manager, like most memory managers, will often put allocations in 
buckets based on their size.  Thus, reducing the size of an allocation may not 
actually yield a useful result.  Specifically:

* If the memory is in a zone that uses fixed sized buckets, it may not be 
possible to reduce the memory that you freed by reducing the size

* The system may not like wasting that much memory and actually trigger a copy 
[1]

The actual behaviour you get definitely varies based on the original size, the 
new size, and the version of the OS on which you’re running.  It may also vary 
based on the current state of the heap.

The upshot of this is that reducing the size of a memory block may not actually 
yield the results you’re looking for.  It might be better to simplify your code 
by:

1. Allocating one maximally sized buffer initially

2. Once you’ve read a ‘packet’ of data into that buffer, create a minimally 
sized data object from that and pass along to the rest of your code

3. Reuse the buffer from 1 for subsequent reads

This will always trigger a copy but a) that copy might have happened anyway, b) 
it will avoid wasting any memory, and c) it’s much simpler.

Share and Enjoy
--
Quinn "The Eskimo!"                    <http://www.apple.com/developer/>
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

[1] Consider this small test project:

static void test(size_t size) {
    void * buffer = malloc(size);
    void * initial = buffer;
    buffer = realloc(buffer, size / 2);
    assert(buffer != NULL);
    if (buffer == initial) {
        fprintf(stderr, "%8zu -> %-8zu didn't move\n", size, size / 2);
    } else {
        fprintf(stderr, "%8zu -> %-8zu moved\n", size, size / 2);
    }
    free(buffer);
}

int main(int argc, char **argv) {
    #pragma unused(argc)
    #pragma unused(argv)
    test(1024);
    return EXIT_SUCCESS;
}

When run on macOS 10.12.4 it prints:

    1024 -> 512      moved

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to