Здравствуйте! Входные данные: $str - строка средней длины (не поток, не файл). Все символы однобайтовые. Выходные данные: обрезанная строка после N символов. Пример: return substr($str, 10000); Функция substr в момент выполнения будет "съедать" память пропорционально размеру обрезаемой части строки. Так при отрезания второй половины от строки размером 500KB пиковое потребление памяти будет равно 750KB. Существуют ли альтернатива функционалу, которая сразу будут отсекать часть исходной строки, не занимая дополнительную память?
Тут важно понять логику: 1) Отдаем строку, N памяти занято. 2) Отрезаем половину, создаем новую переменную, старая никуда не делась, N/2 памяти занято. 3) Это не может произойти ДО того, как будет очищена память из пункта 1. По этому в пике получаем 1.5N памяти. Понимаете? Исходная переменная никуда не делась. Плюс создалась вторая, размером с половину первой. Ваше $str ведь как было, так и осталось вне функции. Даже если вы в нее же переприсваиваете новое значение, все равно, на момент исполнения, она существует в скоупе strpos. Можете попробовать передачу по ссылке, но не факт, что поможет. Боюсь, что бесполезно, ведь strpos уже написан на Си... И, вероятно, оптимизирован настолько, насколько можно. PHP 7+ не двояко намекает, что не дураками это все делается. PHP - это ж, исторически, скриптовый текстовый редактор. Все, что связано с обработкой текста, тут работает на отлично. Лучшей поддержки работы с текстом, пожалуй, я не видел нигде.
Я только не понял при чем здесь strpos Пхп весь на Си написан. Это к теме не имеет отношения. Память под новую строку выделяется, поэтому "пиковый расход памяти" такой. На сях он бы просто символ \0 загнал в нужную позицию и считал бы строку обрезанной. --- Добавлено --- Разница между высокоуровневыми и низкоуровневыми языками в том, что в высокоуровневых вы не паритесь за потраченные байты и потерянные указатели. За удобство приходится платить эффективностью. В большинстве реальных задач это оправдано. Поэтому в телефонах джава и в вебе пхп.
тьфуты...substr, еств. Но ты понял, в общем Не, так не пойдет. У него в итоге расход памяти не изменится. Автор хотел бы 500 до 250 обрезать. А так, у него 500 обрежется визуально, а по факту не изменится. На Си нет строк, автор. Есть char. И есть массивы. Массив char это строка. Память аллоцируется строго статически. То есть. Для строки в 10 символов мы: 1) Выделяем память. 2) Опционально чистим ее от мусора. 3) Заполняем данными. Независимо от того, забили мы или нет данными наш массив, размер его будет тот, который мы определили в пункте 1, сказав ОСи, что нам нужно массив под 10 char-ов запилить. После этого массив неизменен и статичен. Ты можешь читать из него, можешь писать в него. Можешь его дропнуть. Хочешь получить подстроку? Окей: 1) Вычисляешь расстояние между началом и концом подстроки. 2) Аллоцируешь новый фрагмент памяти под пачку char-ов, длиной из пункта 1. 3) Пишешь туда посимвольно данные из исходного массива. 4) Дропаешь исходный, если надо. Итого, между пунктами 3 и 4 у тебя в пике расход памяти достигнет суммарного значения размеров старого и нового массивов. По-другому, увы, никак. Нельзя просто брать оперативку в аренду и резать ее как хочешь. Можно резервировать конкретные ее фрагменты, а потом отдавать обратно. А как же работают динамические охрененные супер-массивы в PHP, Сурикат? А точно так же, только от вас это скрыто на низком уровне. Когда ты объявляешь массив хотя бы с 1 элементов, PHP отгрызает оперативки на 2 элемента. С запасом. Когда ты дошел до 2 элементов, PHP создает новую структуру данных, на сей раз на 4 элемента, копирует в нее предыдущие данные, после чего дропает их. Дошел до 4 элементов? PHP создаст структуру на 8. И так далее, постоянно удваивая. Под капотом старая добрая статика. И это не проблема PHP, просто иначе никак. Да, автор, PHP-массив размером в 129 элементов будет весить в два раза больше, чем массив в 128 элементов. Хотя, конечно, в 7 версии они могли отказаться от линейного роста по степеням двойки и перейти к другому алгоритму аллокации, но степени двойки, обычно, оптимальны.