Как стать автором
Обновить

Комментарии 5

Ох...

В общем, из статьи я вынес, что управлять памятью надо

  • с пристальным вниманием

  • с особой осторожностью

  • строго соблюдая правила безопасности памяти (чем бы это ни было)

  • с глубоким пониманием базовой структуры памяти (тоже не к этой статье)

  • с тщательным тестированием и проверкой кода (не знаю, на что)

Иначе возможны какие-то сбои и ошибки.

В целом – спасибо за статью. В процессе чтения, например, я заинтересовался, как вообще работает withUnsafeMutableBufferPointer, если Array в общем случае не обязательно хранит данные одним куском (в статье об этом не слова, хотя казалось бы...). Ну и заодно погуглил ещё несколько интересных вещей по ходу чтения.

Но...

Во-первых, скажите, пожалуйста, Вы случайно не пользовались какой-нибудь LLM при написании? ChatGPT, Yandex-что-то-там, LLAMA / Alpaca, вот это вот всё. Очень-очень много повторов, общих фраз.

подчеркнув глубокое погружение в низкоуровневые манипуляции с памятью

Насчёт глубокого погружения в низкоуровневые манипуляции я не уверен, но в самой статье я прямо плаваю :)

Во-вторых, осмысленность примеров под вопросом (об этом ниже), эффективность ручного управления не раскрыта, потенциальные проблемы не освещены.

Ну и в целом, я бы подчеркнул, что работа с указателями из Swift – это мазохизм и крайний случай. Если очень хочется, можно ещё рассмотреть вариант с Obj-C обёрткой вокруг C-библиотеки. Так по крайней мере со всеми этими withUnsafeMutablePointer не нужно иметь дело, и можно писать на нормальном C.

Однако это может стать проблематичным, если swiftString выйдет за пределы области действия до того, как printCString завершит выполнение

withCString вызывается синхронно, это понятно уже по декларации функции:

func withCString<Result>(_ body: (UnsafePointer<Int8>) throws -> Result) rethrows -> Result

body не @escaping.

В этом примере класс PixelBuffer выделяет память для экземпляров Pixel в своем инициализаторе и освобождает ее в своем деинициализаторе. Этот подход уменьшает фрагментацию памяти за счет выделения непрерывного блока памяти для данных пикселей. 

Я понимаю, что это пример, но, опять же, вы придумали ухудшенную версию ContinuousArray.

 Например, вы можете реализовать собственный пул памяти для эффективного управления экземплярами класса GameObject:

Опять же, зачем здесь вообще UnsafeMutablePointer? Вы всё равно возвращаете ранее использованный инстанс GameObject, так почему просто не сохранить их в массив? И все проблемы снимает как рукой, не надо "тщательно управлять" никакими жизненными циклами.

Включив такие методы, как подсчет ссылок в небезопасных контекстах, вы можете найти баланс между оптимизацией производительности и безопасностью памяти. Однако помните, что чем больше вы отклоняетесь от автоматического управления памятью Swift, тем большая ответственность за поддержание корректности и безопасности ложится на ваши плечи.

Вот, казалось бы, любопытная деталь, которая выглядит реально полезной, но что это за метод? Как его включить? Какие ещё "методы" можно включить? (написано "такие, как") Я предполагаю, что это флаг в target-е, наподобие zombie objects, так? Но в таком случае о каком балансе идёт речь? Оно может помочь обнаружить проблемы, какой вообще может быть баланс между оптимизацией и безопасностью памяти? Память или безопасна, или нет, она не может быть "немножко небезопасна, но зато у нас функция на полмиллисекунды быстрее работает". Точнее, может, конечно, но если пришла мысль написать такой код, надо или поспать, или идти в хаб "ненормальное программирование".

Реализовав связанный список с нуля, вы получите представление о тонкостях низкоуровневых манипуляций с памятью.

Так может быть вот это должно было быть статьёй?

небезопасный подход может обеспечить преимущества в производительности в определенных сценариях

Я вижу два практически идентичных фрагмента кода и общее утверждение, что один работает быстрее, чем другой. Где деньги, Лебовски? Неплохо бы в таком случае иметь хотя бы самые поверхностные тесты, которые это подтвердят. При этом вполне допустимо выбирать случаи, когда у ручного управления будут преимущества (хотя в идеале представить также и случаи, когда это не так). Но тут вообще никаких тестов нет.

Спасибо за такой развернутый комментарий!

Да, пользовался нейросетями и видимо стоило больше времени потратить на редакцию текста, учту при следующих статьях и спасибо за замечание.

В-принципе спасибо за все замечания, понял что сильно расфокусился на общую тему и надо было больше вглубь копнуть и что примеров не хватило.

Извините, если я немного резко, то же самое можно более корректно написать, я стараюсь над собой работать, но пока не достиг больших высот, к сожалению. В любом случае со статьёй лучше, чем без статьи :)

Могу ошибаться, но сложилось впечатление, что сначала боремся за то, чтобы управление памятью было автоматическим и безопасным, потом натыкаемся на то, что в ряде случаев это дает просадку в производительности и пытаемся управлять памятью самостоятельно, но при этом боремся с автоматическим управлением чтобы оно нам кислород не перекрыло в самый неподходящий момент.

Для "динозавров", которые начинали с 80-90-х (и к коим смею себя причислять) на "чистом С", ручное управление памятью делается уже на подсознательном уровне. Это такая годами воспитанная дисциплина ума, не вызывающая каких-то проблем и/или дискомфорта. Скорее автоматическое управление порой вызывает некоторое раздражение - "оно чего-то там само делает, мной неконтролируемое" и к этому тоже нужно привыкать.

И, честно говоря, не возьмусь однозначно утверждать что лучше или хуже.

Написал маленькое, но важное дополнение к этой статье о выделении совместно используемой памяти

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации