Форум сайта python.su
виноват =D
Офлайн
=D
Кстати, именно поэтому все перечисленные способы могут не сработать (на utf8 файлах в частности).
Прыгнув в произвольное место, нельзя уверенно установить: ‘\n’ - это переход на новую строчку или часть символа, закодированного несколькими байтами.
Вывод - используйте исключительно ascii в ваших логах :)
Офлайн
Андрей, большое спасибо за твои разъяснения. Все стало на свои места.
С другой стороны, результат работы вполне определен - просто seek работает с байтами, а не с символами, вне зависимости от того, как открыт файл. И никакой магии.Так бы и написали.
К тому же, потенциальные проблемы относится только к произвольному доступу. Если мы просто перебираем файл в обратном порядке, то нам, по большому счету, все равно, в каком режиме он открыт. И мой код будет нормально работать с многобайтными кодировками. Надо только отказаться от предположения, что файл заканчивается переводом строки, а то в случае какого-нибудь “ё” последняя буква сломается - но это детали.
Более того, в коде у doza_end строка может оказаться длиннее MAX_ROW и seek точно также может попасть в середину многобайтного символа (shit happens). То есть сивол выйдет поломанным - тоже мелочь, но неприятно. Соответственно, ‘rb’ в open - это совсем не решение обсуждаемой проблемы.
Еще раз, вывод: документаторам - незачет: понять что они имели ввиду, можно только зная, что они имели ввиду =D
SO
Отредактировано (Ноя. 27, 2010 00:49:45)
Офлайн
Андрей, не прочел твой последний пост, проводил эксперименты над русскими текстами =D
Мой код будет работать даже с китайским ;)
Потому что там нет произвольного доступа, просто перебор с конца - символов или байтов - ему все равно.
Офлайн
А вот это я уже не понимаю.
Мне ясно, почему символы будут пониматься правильно, если читать поток с начала.
И решительно непонятно, как это сделать в общем случае при чтении с конца.
Допустим, в случае с utf-8 все просто - никакой многобайтный символ не сможет содержать внутри ‘\n’.
Для другой кодировки - иные правила. И я не уверен, что у всех кодировок ‘\n’ (байт с кодом 10) не сможет
встретится в середине символа.
Эти китайцы - они такие странные люди, мне мама говорила.
К слову, пробежка по файлу из 25000 строк (взял оочень длинный fb2 на 6 Мб, строки там по абзацу, т.е. тоже весьма большие) - так вот, вычитка всех строк занимает 7 миллисекунд.
На настоящем моем логе на те же 26000 строк (но размером в 1.8 Мб) прочитать все строки занимает 3 миллисекунды.
Стоит ли огород городить?
Офлайн
Андрей Светловтак и есть, на файлах в кодировке utf-8 - не работает (ось - windows). т.е. открывать нужно только в бинарном режиме. (я это еще в прошлом веке усвоил :))
Кстати, именно поэтому все перечисленные способы могут не сработать (на utf8 файлах в частности).
Офлайн
Более того, в коде у doza_end строка может оказаться длиннее MAX_ROW и seek точно также может попасть в середину многобайтного символа (shit happens). То есть сивол выйдет поломанным - тоже мелочь, но неприятно. Соответственно, ‘rb’ в open - это совсем не решение обсуждаемой проблемыЯ что-то не понял. Первая часть предложения - по поводу строка окажется длиннее. Она не окажется в силу заявленного ограничения (которое можно установить при записи лога). Но по-моему это не имеет отношения к делу.
Стоит ли огород городить?Как всегда зависит от задачи. У нас есть такая штука логи полномасштабного тренажера. За рабочий день 4-5 часов набирается 1-3 гигабайта. Довольно часто надо последнюю тысячу сообщений загрузить после некоторого момента времени. В этом случае может довольно сильно подтормаживать.
Отредактировано (Ноя. 27, 2010 08:49:59)
Офлайн
Для гигабайтных логов я, наверное, строил бы индекс. Например, с секундными отметками.
А затем, быстро прыгнув на ближайшее время в индексе - снова прокрутил бы вперед до нужной записи.
Программы - это не только быстрые алгоритмы но и оптимальные структуры данных :)
P.S. А откуда информация о 4-8 Кб кеше? Допускаю, что у stdio размер буфера примерно такой. Но у дисковой подсистемы буфер должен быть изрядно побольше, думаю. Плюс к тому же многомегабайтные кеши у собственно жестких дисков.
И вся эта машинерия должна быть оптимизирована на упреждающее чтение - единственно годная стратегия в общем случае.
Офлайн
А мы так и делаем (трехуровневый индекс поскольку эта гадость иногда дня по 4 круглосуточно пашет) :). Блоки нижнего уровня грузятся целиком.
Файл большой 15 - 20 кк строк.:)
Короче - не один вариант не подходит.
Офлайн
По поводу кэша. Я наверное неясно написал. Извините. Я писал, что операционка на уровне ядра оперирует кусками (блоками ) по 4-8к, но не то что весь кэш такого размера. Информация - слухи :). Я говорил с человеком который у нас исследовал этот вопрос для винды и нескольких клонов linux. Его методки-какое-то страшное ковыряние отладчиком в ядре с моей точки зрения - магия. Вопрос был про ток как raid влияет на скорость. По поводу размера буферов вы правы - десятки мегабайт. Вы мне кажется правы все это заточено на упреждающее чтение вперед.
Люди могут попробовать например почитать большой файл (мегов 100) вперед и поделать по нему random seek в питоне. У меня получалось что обмен винчестером как и положено десятки мегабайт в секунду на на каждый seek надо 0.01 сек
Офлайн