Оптимизирует ли PHP последовательные команды fseek в одну команду fseek?
Я запускаю Windows 7 - 64 бит, с последней версией XAMPP, которая имеет 32-разрядную версию PHP.
при тестировании http://php.net/manual/en/function.fseek.php#112647 для очень большого файла (больше, чем PHP_MAX_INT 2147483647) я теперь уверен, что последовательно следующие fseeks суммируются перед выполнением на filepointer.
У меня два вопроса:
могу ли я разорвать это подведение итогов с разумным означает (или только с обходным путем, упомянутым в ссылке выше)?
эта агрегация происходит в PHP (как я предполагаю, хотя я не знаю, где в PHP) или в Windows 7?
отвечая себе: попытка двух обходных путей с несколькими поисками не сработала на моей системе. Вместо этого они помещают filepointer в разные позиции в соответствии с PHP_MAX_INT. (32-битный PHP может искать только до PHP_MAX_INT + 8192. Чтение оттуда еще возможно, но я не знаю, как далеко.)
поэтому вопрос устарел для моего конкретного случая, а 32-битный PHP может искать только до PHP_MAX_INT + 8192, что бы вы ни делали. Я оставьте вопрос, потому что два человека проголосовали за него и могут быть интересует общий ответ.
Я подал сообщение об ошибке здесь:
https://bugs.php.net/bug.php?id=69213
Результат: с 64-битной сборкой PHP это может сработать, но я не пробовал он.
2 ответов
это не так. Он действительно что-то делает еще тупее. вот фрагмент из исходного кода PHP:
switch(whence) {
case SEEK_CUR:
offset = stream->position + offset;
whence = SEEK_SET;
break;
}
Это находится в кишках реализации для PHP fseek
. Что здесь происходит: если вы говорите PHP искать с текущей позиции, это переводит это в "эквивалентный" поиск с самого начала файла. Это работает только тогда, когда это смещение вычисление не переполняется; если это так, хорошо,offset
является целым числом со знаком, поэтому это не определено поведение.
и, хорошо, это потому, что PHP-буферы потоки внутри, поэтому им нужно сделать что-то. но это не обязательно должно быть так.
вам, вероятно, лучше всего пытаться делать свою работу на языке, который на самом деле делает то, что вы говорите.
Если бы агрегация должна была произойти, это, вероятно, должно было бы быть оптимизацией кода операции или должно было бы произойти на низком уровне через буфер.
Я могу ответить на низком уровне. fseek () в php реализован с использованием PHP потоков. Он объявлен в ext/standard / file.h и определено в .c. Его реализация вызывает php_stream_seek (), который вызывает через _php_stream_seek () в потоках.c. Низкоуровневая реализация этого обрабатывается через оболочку plain streams, в этом случае ищите вызовы через zend_seek или zend_fseek, которые, в свою очередь, просто сопоставляются с 32 или 64-битным искать _seeki64 c звонки.
Так... если какая-либо агрегация происходит, она, похоже, должна быть в оптимизации кода операции или даже ниже в ОС или оборудовании. Жесткие диски реализуют неупорядоченную выборку, чтобы уменьшить расстояния поиска головки, и системы буферизации файловой системы могут уменьшить запросы, которые не имеют побочных эффектов. Если вы беспокоитесь о диске время чтения, первый автоматически обрабатывает это. Если вас беспокоит, возможно, избиение памяти (излишне искать большие расстояния в буфере), вы можете рассмотреть другой подход. Смотри:http://www.cs.iit.edu / ~cs561/cs450/disksched/disksched.html для получения дополнительной информации о том, как диски не тратят время поиска.
надеюсь, это поможет.