![]() |
Модераторы: skyboy, MoLeX, Aliance, ksnk |
![]() ![]() ![]() |
|
TSVET |
|
||||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 6.9.2007 Репутация: нет Всего: нет |
Читал книгу "PHP 5 в подлиннике", там о функции file() говорится что не следует загружать ей файлы большого объёма. О функции fgets() говорится что она медлительна с большим объёмом данных. Поэтому я ради интереса решил изобрести велосипед,- написать свою функцию которая будет грузить не весь файл и не по одной строчке, а строк сразу по ~200 приблизительно, обрабатывать эти строки, затем опять грузить ~200 строк, и так пока данные в файле не закончатся. Я выбрал объём загружаемых данных равный одному мегабайту, но думаю, этот объём можно увеличить.
Взят простейший пример: в файле например 30мегабайт текста, каждая строка это веб-страница. В среднем строка имеет объём 10килобайт. За один запрос к скрипту нам надо выдавать одну страницу, а значит, за один запрос нам нужна всего одна строчка.
Вот сам текст, который мы обрабатываем:
Но как говорилось выше, он имеет не 10 строк, а несколько десятков мегабайт. Как видно, если структура проста, и к файлу нет множества обращений на чтение\запись, то можно обойтись и без MySQL Чтоб убедиться, что этот код работает я ставил в циклы счётчик, убирал BREAK из циклов, менял метод убирал fread() и fgets(), и выводил число, которое натикало на счётчике. Функция работает как задумано. Но цель функции - сохранить допустимую нагрузку на сервер, и сохранить приемлемую скорость выполнения. Я БЫ ХОТЕЛ ВАС СПРОСИТЬ: добивается ли эта функция поставленных задач? Стоит ли вобще игра свеч? ______________________________ Также я когда-то пытался написать аналогичную функцию для записи, которая работает так: 1. Читает блок из обрабатываемого файла 2. Обрабатывает его построчно 3. Пишет блок во временный файл(цикл повторяется пока функция не перепишет все данные во временный файл) 4. Копирует обработанный временный файл на место старого Но функция не работала по неизвестной мне причине, то ли временный файл не создавался, то ли в него ничего не писалось, а может он не копировался на место старого... P.S.: естественно такая функция не расчитана на множество частых запросов записи, а вот там где их немного(админпанель) вполне сойдёт. |
||||
|
|||||
Feldmarschall |
|
|||
Новичок ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2641 Регистрация: 11.12.2007 Репутация: 22 Всего: 32 |
Хороший пример кривизны.
Можно на наглядном примере изучать, как делать не надо. Криво тут всё: постановка задачи, сама решаемая задача, применяемые средства. Для чего мы городим весь этот огород? Чтобы обойтись без базы данных. Понимаешь, какое дело... Кабы помягче сказать. Вот, допустим, приходишь ты на авто.ру, и говоришь, что придумал устройство, которое позволяет запрягать лошадь в автомобиль любой марки. И при поездках на небольшие расстояния оно вполне позволяет обойтись без бензина. Как ты думаешь, какова будет реакция? Здесь примерно то же самое. Дальше переходим к исходным данным.
Изумительно. Что такое "медлительна", что такое "большие объемы" - не знает никто. Но при этом данная информация берется за некую отправную точку в изысканиях. И вера книжкам - просто поразительная. fgets даже не участвует в экспериментах. Медлительна - и баста! Пример, выбранный для исследования не менее замечательный. Несомненно, половина вебсайтов именно так и поступают - записывают 3000 страниц в один файл. Отличная идея, очень перспективная. Несомненно, её надо решать. Ну, и средства. Экономим производительность. Именно в этих целях мы и тягаем в память строку на два мегабайта, парсим её в массив и ходим по нему в цикле ради одной-единственной строчки. Браво. Эталон оптимальности. |
|||
|
||||
TSVET |
|
||||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 6.9.2007 Репутация: нет Всего: нет |
Если брать эту функцию в цикле, и ходить по всему файлу, хотя в моём коде тоже аж два цикла, так что ожидать прироста производительности моего кода не приходится. Я ведь не со зла написал этот код, я думал так будет лучше))))) Жила-была одна ЦМС написанная на файлах без мускуля, только она грузила файлы целиком... А в каментах ведь срут, файлы раздуваются(я б никогда не стал хранить форум или каменты в файлах) Работала причём эта цмс, но потом их закрыли за большую нагрузку на сервер, а вот еслибы они через fgets() делали, или как я то их не закрыли бы...
Я не говорю, что сайты будут хранить столько страниц в одном файле, но предусмотреть это нам никто не мешает. Притом работать это будет не нагружая сервер, а то что в файле будет столько страниц то врядли... А ведь мускуль тоже перебирает всё, только он на Си писан и там всё быстрее... и продуманно более умнО и разносторонне... А вообще бувает, придумаешь как кажется что нибудь "гиниальное", а на деле полный бред выходит... Меня интересует, как вы относитесь к txtSQL? Тот же мускуль, только на ПХП. Что мешает реализовать мускуль на ПХП? ПХП слабый язык? txtSQL живёт, значит что-то здравое в этом ведь есть?.. |
||||
|
|||||
Feldmarschall |
|
|||
Новичок ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2641 Регистрация: 11.12.2007 Репутация: 22 Всего: 32 |
Так и я не со зла её раскритиковал.
Я рад, что ты нормально это воспринял. Просто на твоем примере хорошо видно, что обдумывать надо все этапы своей работы - от предпосылок до реализации.
на самом деле, вариантов масса. сколько бы ни было каментов - их число всегда достаточно разумное(если только их защищать и чистить от спама - если не защищать, то тут любая база быстро подохнет) и работа с ними всегда будет нормальной, если грамотно структурировать. К примеру, каменты под статьёй - для каждй статьи свой файл. Нет, мешает. Вообще, попытки что-то предусматривать без достаточного опыта, обычно приводят к обратному результату. Сколько компьютерщиков тратили бешеные бабки, покупая последнюю модель материки или видюхи, "под апгрейд". И как жестоко накалывались, когда ко времени апгрейда проц уже имел другой сокет, а видюха - стандарт. И так во всем. Брать надо на сейчас. В будущем у тебя изменятся требования, задачи, и продходы к их решению. Ты потратишь время на универсальное решение, которое тебе не понадобится. В программировании ещё хуже. Сейчас ты не понимаешь разницу между решаемыми задачами. Они тебе кажутся одинаковыми. Но это не так. Для страниц умнее - держать их в отдельном файле. Для других задач - другие решения. Не надо искать универсальное. Если у тебя есть проблема - зайди на форум и задай конкретный вопрос. Тебе дадут конкретное удобное решение. А вот и не угадал! Мускуль, вообще-то, тоже не что-то застывшее и однообразное. Одних движков хранилищ в нем десяток. Но если обращаться к хрестоматийной БД, то там все гораздо проще и быстрее. Во-первых, открой для себя волшебную функцию fseek(). Которая ,при умелом использовании, ускорит твой код в разы. Во-вторых, если выравнивать строки по длине, то поиск нужной будет занимать и вовсе ничтожное время. В-третьих, если нам понадобится искать данные по ключевым словам, то мы сделаем индексный файл, который будет в сотни раз меньше файла с данными, который мы будем целиком читать в память, находить в нем номер строки с нужным ключевым словом и выбирать эту строку с помощью fseek, и ворочать таким образом громадными базами. Поздравляю! Ты изобрел БД! Теперь осталось её отладить и обкатать на паре стоен проектов и она готова... Вот только зачем ,если это уже сделали до тебя? извини, но логики в этом заявлении нет никакой. бомжи как-то живут? кому-то нравится быть бродягой - значит, что-то здравое в этом есть? Возможно. давай, подавайся в бомжи. если следовать твоей логике. если что-то где-то живет - это СОВСЕМ не повод напяливать это на себя. |
|||
|
||||
Kaiden |
|
|||
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 26.11.2007 Репутация: нет Всего: нет |
Просто небольшое замечание по коду.
У команды break есть опциональный параметр, который указывает, из скольких вложенных циклов нужно выйти. Т.е. вместо некрасивого использования булевой переменной stop, можно было просто написать break 2. Что касается самой функции... На мой взгляд, она могла бы быть полезна при решении какой-то очень узкой задачи - когда, допустим, из файла в два миллиона строк надо выбрать одну строку, т.е .как в примере выше. Но при текущей реализации такая функция скорее всего проиграет в скорости построчному чтению файла через gets(). Да и задача такая не должна возникать. |
|||
|
||||
TSVET |
|
|||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 6.9.2007 Репутация: нет Всего: нет |
Скорее такая задача поставлена от нечего делать. И задача эта такова: сделать что-то абсурдное(обойтись без мускуля), но чтоб это было вполне рабочим. А потом когда это реализовано, торжественно ударить в бубен и крикнуть: БРАВО! Я изобрёл велосипед!
![]() Задача не столько практическая, сколько познавательная. Я думаю, что пойму как работает простейшая БД. А вообще, спасибо за здравую критику, и разъяснение про fseek(), я тоже вначале думал про индексный файл и про fseek(), но потом почему-то забыл... А вообще fseek() это и есть ответ на мой вопрос, это правда убило весь смысл моего кода. Можно поступить так: по-прежнему структура - каждая строчка это страница. Храним в индексном файле положение каждой строчки в байтах. Подъезжаем к строке fseek'ом, вытягиваем её fgets'ом. Храним ID страниц + положения файлового указателя соответствующих строк, и Title страницы. Пример индексного файла:
И на последок: Если мы меняем положение страницы, то оперируем только с ID'шниками в индексном файле. Если мы удаляем то читаем по одному мегабайту fread'ом, перекидываем во временный файл. Если расстояние от позиции с которой читаем до позиции удаляемой строки меньше одного мегабайта, то указываем fread'у прочитать с текущей позиции до позиции удаляемой строки. Перекидываем во временный файл. Пропускаем вхолостую fgets'ом удаляемую строку, не перекидываем её во временный файл. Продолжаем читать fread'ом по мегабайту с позиции конца удаляемой строки, перекидываем во временный, так повторяем цикл до конца файла. Копируем временный файл на место старого. УРА! Я мозгоё... мозголом! ![]() Всё это я делаю ради того, чтоб мозги не засохли. Так что не следует воспринимать это вштыки! Ну и на последок, ради пущего мозголомства я думаю за хорошие деньги нанять программиста, который реализует простую ЦМС на этом принципе. Если меня конечно не пошлют куда по-дальше... Я РАСЧИТЫВАЮ ПОЛУЧИТЬ ГРАНТ ЗА САМЫЙ АБСУРДНЫЙ ПРОЕКТ. ![]() |
|||
|
||||
Feldmarschall |
|
|||
Новичок ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2641 Регистрация: 11.12.2007 Репутация: 22 Всего: 32 |
||||
|
||||
TSVET |
|
|||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 6.9.2007 Репутация: нет Всего: нет |
Точнее меняем местами строки в индексном файле.
Наверное если попытаться придумать мускуль, то мозг расплавится. Не стоит так рисковать мозгами ![]() |
|||
|
||||
Feldmarschall |
|
|||
Новичок ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2641 Регистрация: 11.12.2007 Репутация: 22 Всего: 32 |
TSVET, ты запутаешься.
В принципе, мысль верная: индекс - это и есть файл, заранее отсортированный по ключевому полю. Но из этого следует, что менять порядок ID - нельзя. Если нужна сортировка, то надо для неё заводить другое поле. |
|||
|
||||
TSVET |
|
|||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 6.9.2007 Репутация: нет Всего: нет |
О, уже количество полей увеличивается. Как же их все обрабатывать-то.
Если количество полей продолжит расти, то на индексный файл придётся создавать еще один индексный файл)))))... шучу. Сномневаюсь... даже если дать такое техническое задание даже очень хорошему программисту, то думаю даже он сломает голову... или всё это выльется в круглую сумму. хм. Открытие: всё это может и будет работоспособным. Только вот от мускуля будет отличаться вот чем: если мы захотим расширить функционал, добавить новую фичу то тут врядли что-то выйдет. Это не мускуль. Здесь нет аналогов мускульных запросов. Всё хорошо до тех пор, пока структура хранимых данных проста, и особых требований к запросам нет. Хотя даже с простыми данными не вполне ясно как реализовать нормальный поиск. Поскольку это всё страницы в ЦМС, то надо выводить еще и меню, а так как в задуме оно трёхуровневое древовидное, то в индекс добавляется еще одно поле, в котором цифры 1, 2 или 3 указывающие на уровень пункта в меню. Ужос. Как-то я сбоку посмотрел на свои рассуждения, представил себя идиотом ![]() Файло-фетишизм... |
|||
|
||||
![]() ![]() ![]() |
Правила форума "PHP" | |
|
Новичкам:
Важно:
Внимание:
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | PHP: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |