Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Pavel Dvorkin, Вы писали:
IT>>>Именно. Глупо себя мнить самым умным, особенно среди студентов. PD>>Это ты себя студентом считаешь ?
IT>Всё время учиться — неотъемлемая часть моей профессии
Это правильно
>так что можно и так сказать. Но в данном случае я имел ввиду твоих студентов.
Они тоже учатся.
IT>>>У тебя с логикой всё в порядке? Это не я бурусь давать советы, ничего не зная о твоей задаче. Это ты требуешь у всех выдать тебе решения не давая при этом ни какой информации.
PD>>Не увиливай. Я тебе конкретно задачу дал (демо) — сложение двух матриц. Тут все и полностью определено.
IT>"Полностью определено" из тебя пришлось щипцами вытягивать.
Пусть даже так, хотя я и не согласен. Вытянул ? Давай решение. Только без разговоров о распараллеливании.
IT>>>Тебе рассказать как параллелить обработку двумерных массивов, рассказать про пул потоков и операцию деления 5000 (или сколько у тебя там) на 16?
PD>>Я тебе ясно сказал — смысла параллелить нет, так как гораздо проще одновременно обрабатывать несколько матриц, по одной на ядро.
IT>А это разве называется не распараллеливание?
Безусловно да. Но к делу отношения не имеет.
PD>> Можешь объяснить, чем это лучше распараллеливания каждой малой матрицы на все ядра ?
IT>Дворкин, я сейчас умру со смеху
Постарайся все же остаться в живых
>На твоё предложение ускорить твой алгоритм в 10 раз, я тебе сразу предложил взять 16 ядер и распараллелить твой алгоритм. То ли это распараллеливание одной матрицы, то ли потока — это детали. Если бы у меня было больше информации, я бы тебе предложил что-то более конкретное.
Ты даже простую вещь не понимаешь. Взять 16 ядер — это не ускорение алгоритма. Это использование дополнительных ресурсов при неизменной (а то и хуже) скорости алгоритма. С таким же успехом можно предложить вместо Pentium 100 взять Pentium 4 3000 и сказать — мы ускорили в N0 раз. Ничего тут не ускоряется и нет никаких заслуг программиста в этом.
Я поэтому тебе и сказал про 16 компьютеров. Велика мудрость — взять вместо одного компьютера 16 (или 16 ядер) и сказать — мы ускорили в 16 раз. К оптимизации алгоритма это вообще отношения имеет очень мало. Ты вот на одном ядре сделай, чтобы он работал быстрее, вот это будет результат.
IT>Ты опять не понял. Если человек спрашивает совета или предлагает решить задачу, то он либо должен уточнить условия, либо должен дальше уже сам выбирать наиболее подходящий вариант из предложенных. На твой вопрос "как ускорить обработку матриц" (именно так, без дополнительных условий), ты получил ответ — возьми 16 ядер и распараллель свой алгоритм. Что в этом ответе не понятного?
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Я себе живо эту ситуацию представляю. Приглашают тебя и просят написать программу, которая 100 Гб текстовый файл на строчки парсит. На это ты отвечаешь — у меня есть замечательное решение, я его даже спросонок могу выдать за 10 сек, только, пожалуйста, купите мне машину с 256 Гб ОП
IT>Повторенье — мать ученья. Давай сначала.
IT>Когда меня 'приглашают и просят написать программу, которая 100 Гб текстовый файл на строчки парсит', то мне уже задают вполне конкретые условия, от которых зависит реализация. Вот так и надо делать, если ты хочешь получить ожидаемое решение.
Слава богу, хоть в чем-то я могу с тобой согласиться. Только вот именно это я везде и твержу — решение надо давать применительно к условиям. А не советовать ReadAllLines + Split, не зная этих условий.
>Ты же обычно в своих постановках задачи эти важные детали только подразумеваешь.
Ладно, пусть я подразумеваю. Но зачем все же ты с этим чтением последней строки так упорствуешь в своем решении ? Задача там не моя, но ты почему-то у автора не стал спрашивать этих деталей, а сходу выложил свое универсальное однострочное решение, да еще и сейчас его отстаиваешь, аргументируя тем, что за 10 сек его можно написать.
Давай прямо — для хотя бы 500 Мб файла — ты по-прежнему утверждаешь, что твое однострочное решение годится ? Да или нет ?
>А ещё чаще твоя вая твоя постановка задачи сводится к 'приглашают и просят написать программу'. Пока ты не научишься чётко ставить перед человеком проблему, ты будешь получать решения, вполне приемлемые в условиях, которые тебя не устраивают. Так научись чётко ставить задачу и всё у тебя получится.
А с чего ты решил, что у меня что-то не получается ??? . До сих пор все получалось.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, fmiracle, Вы писали:
F>>В реальной задаче, столкнувшись с проблемой, что файлы стали уже по 500Гб и кусочек кода от IT с получением последней строчки жутко тормозит — там, может быть, применят оптимизацию, и перепишут этот маленький кусочек кода в боле большой и умный.
IT>При этом вся оптимизация может свестись к замене методов GetAllLines().Split() на версию с перечислителем, которая внутри исползует потоковый или какой другой эффективный доступ к файлу. И овцы сыты и волки как говорится. Но это очень сложно объяснить товарищам, жаждущим оптимизаций в каждой строчке кода.
да оставьте вы в покое тов. Дворкина. Никто в здравом уме не хочет миллионов оптимизаций в миллионах строк кода. Речь идет о том что некоторые отрасли имеют типичные ожидания пользователей, закрепленные многими реализациями. И если платформа под них не не адаптирована, то никакой разумной заменой методов это не сделать. В качестве примера (как можно дальше от своей отрасли где даже опенсорс под нда) могу привести блог разработчиков Unity, которые были не очень счастливы когда выяснилось что большую часть стоимости портирования моно на яблофон им придется заплатить самим Причем это успешный пример тк они это сделали и это было дешевле. (вброс) А теперь добавьте-ка им туда linq и все фичи 3.5 или 4.0
а какой вывод ? топегстартера интересовала секьюрити. Обсудили: часть народа интересовала свобода, а часть минимизация усилий и всем было плевать на секьюрити, кроме случаев когда юзеры ее специфицировали и не отвертеться. Предложенная замена языка реализации не заинтересовала никого тк писать на специально "обезопасенном" языке добровольно никто не захочет.
PD>>Я все же не понял. IEnumerable (то есть чтение по одной строке, так ?) — конечно лучше, но зачем вообще все строки читать, если нужна последняя ? S>Когда встанет задача обеспечить адаптацию уже написанного кода, который читает все строки, к большим файлам, я возьму и адаптирую его (а не перепишу заново).
Его — перепишешь. Просто тот вариант не пройдет в принципе, поэтому придется сменить алгоритм. Ну хотя бы с IEumerable.
PD>>Ничего себе не хуже! Чтобы получить одну последнюю строку, ты считал файл целиком, пусть и построчно. Кстати, чтобы считать построчно, есть там у вас что-то вроде gets ? ReadLine не пойдет ? Ну и читай себе построчно, не надо никакие IEnumerable в ReadAllLines засовывать. S>Да, есть StreamReader.ReadLine(). Но он мне не совсем подходит, т.к. первоначальное решение использовало массив строк из File.ReadAllLines(). Безболезненно я ее могу заменить только на IEnumerable<string>. Потому StreamReader.ReadLine() придется обернуть в IEnumerable, чтобы не переписывать все решение.
Хм... А стоит ли ? Обернуть, конечно, можно, но, честно говоря, сделать просто замену кода — работы на полчаса. Кстати, никакого IEnumerable пока что в варианте IT нет, это тоже надо делать. Так не проще ли выкинуть его решение и сделать чтение по строкам(я сейчас абстрагируюсь от того, что это тоже не хорошо, временно допустим, что хорошо), чем насильно пытаться то решение адаптировать. Зачем ?
PD>>Но ведь читать-то не надо. S>У меня некоторые пробелы на тему кодировок. Я вот не уверен, что при чтении файла задом наперед, или какими-то кусками не с самого начала, можно гарантированно идентифицировать символы конца строки.
По крайней мере для ASCII-8, UTF-8 и Unicode 0D0A всегда на месте (для юникода, конечно, short). Что касается всех возможных на свете форматов — как говорится. я вам не скажу за всю Одессу. Но тут опять же истина конкретна. Если речь идет о возможности чтения всех и всяческих форматов — тогда стоит подумать. Ну а если ясно, что никаких экзотических форматов не будет — вперед и с песнями.
>Это еще одна причина, по которой я бы текстовый файл читал только последовательно.
Слишком дорогая плата. Ты обеспечишь, что программа будет корректно работать с экзотическими форматами, но заткнется на файле в 5-10 Гб (с IEnumerable по времени, в варианте IT — по нехватке памяти ). Я этот файл обработаю, но проблемы будут с экзотикой . ИМХО второе лучше.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, samius, Вы писали:
S>>Когда встанет задача обеспечить адаптацию уже написанного кода, который читает все строки, к большим файлам, я возьму и адаптирую его (а не перепишу заново).
PD>Его — перепишешь. Просто тот вариант не пройдет в принципе, поэтому придется сменить алгоритм. Ну хотя бы с IEumerable.
Две строчки скорее всего перепишу. Но если речь пойдет о задаче большей — буду пытаться адаптировать.
S>>Да, есть StreamReader.ReadLine(). Но он мне не совсем подходит, т.к. первоначальное решение использовало массив строк из File.ReadAllLines(). Безболезненно я ее могу заменить только на IEnumerable<string>. Потому StreamReader.ReadLine() придется обернуть в IEnumerable, чтобы не переписывать все решение.
PD>Хм... А стоит ли ? Обернуть, конечно, можно, но, честно говоря, сделать просто замену кода — работы на полчаса. Кстати, никакого IEnumerable пока что в варианте IT нет, это тоже надо делать.
Нет? А что там есть? Массив строк? Если честно, я его в точности не помню.
PD>Так не проще ли выкинуть его решение и сделать чтение по строкам(я сейчас абстрагируюсь от того, что это тоже не хорошо, временно допустим, что хорошо), чем насильно пытаться то решение адаптировать. Зачем ?
Конкретно в этой задаче может и проще. В других случаях будет проще адаптировать, даже не разбираясь в сути алгоритма.
S>>У меня некоторые пробелы на тему кодировок. Я вот не уверен, что при чтении файла задом наперед, или какими-то кусками не с самого начала, можно гарантированно идентифицировать символы конца строки.
PD>По крайней мере для ASCII-8, UTF-8 и Unicode 0D0A всегда на месте (для юникода, конечно, short). Что касается всех возможных на свете форматов — как говорится. я вам не скажу за всю Одессу. Но тут опять же истина конкретна. Если речь идет о возможности чтения всех и всяческих форматов — тогда стоит подумать. Ну а если ясно, что никаких экзотических форматов не будет — вперед и с песнями.
UTF-16 — экзотика? Нет, там символы перевода строки не кодируются, но это уже будет не 0D0A!
>>Это еще одна причина, по которой я бы текстовый файл читал только последовательно.
PD>Слишком дорогая плата. Ты обеспечишь, что программа будет корректно работать с экзотическими форматами, но заткнется на файле в 5-10 Гб (с IEnumerable по времени, в варианте IT — по нехватке памяти ). Я этот файл обработаю, но проблемы будут с экзотикой . ИМХО второе лучше.
Потом заказчик решит, что 5-10Гб текстового файла — слишком жестко для диска (или передачи по сети). И предложит зазиповать тексты.
Вот тогда мы с IT изменим одну строчку, а тебе придется опять переписать все!
Но это все к теме о выдумывании условий, чтобы коню в вакууме скучно не было.
Здравствуйте, samius, Вы писали:
S>Две строчки скорее всего перепишу. Но если речь пойдет о задаче большей — буду пытаться адаптировать.
+1. Вообще-то граница между адаптацией и переписыванием несколько размыта. В любом случае — изменять, больше или меньше.
S>>>Да, есть StreamReader.ReadLine(). Но он мне не совсем подходит, т.к. первоначальное решение использовало массив строк из File.ReadAllLines(). Безболезненно я ее могу заменить только на IEnumerable<string>. Потому StreamReader.ReadLine() придется обернуть в IEnumerable, чтобы не переписывать все решение.
PD>>Хм... А стоит ли ? Обернуть, конечно, можно, но, честно говоря, сделать просто замену кода — работы на полчаса. Кстати, никакого IEnumerable пока что в варианте IT нет, это тоже надо делать. S>Нет? А что там есть? Массив строк? Если честно, я его в точности не помню.
ReadAllLines в буфер + Split
PD>>Так не проще ли выкинуть его решение и сделать чтение по строкам(я сейчас абстрагируюсь от того, что это тоже не хорошо, временно допустим, что хорошо), чем насильно пытаться то решение адаптировать. Зачем ? S>Конкретно в этой задаче может и проще. В других случаях будет проще адаптировать, даже не разбираясь в сути алгоритма.
Все может быть. Я тоже не любитель переделывать все заново, но еще меньше люблю за уши притягивать. Стройность системы страдает.
S>>>У меня некоторые пробелы на тему кодировок. Я вот не уверен, что при чтении файла задом наперед, или какими-то кусками не с самого начала, можно гарантированно идентифицировать символы конца строки.
PD>>По крайней мере для ASCII-8, UTF-8 и Unicode 0D0A всегда на месте (для юникода, конечно, short). Что касается всех возможных на свете форматов — как говорится. я вам не скажу за всю Одессу. Но тут опять же истина конкретна. Если речь идет о возможности чтения всех и всяческих форматов — тогда стоит подумать. Ну а если ясно, что никаких экзотических форматов не будет — вперед и с песнями. S>UTF-16 — экзотика? Нет, там символы перевода строки не кодируются, но это уже будет не 0D0A!
Точно не кодируются ? В классическом Юникоде кодируются, только , естественно, wchar_t, а не char. А UTF-16 вроде как отличается лишь наличием суррогатных пар.
>>>Это еще одна причина, по которой я бы текстовый файл читал только последовательно.
PD>>Слишком дорогая плата. Ты обеспечишь, что программа будет корректно работать с экзотическими форматами, но заткнется на файле в 5-10 Гб (с IEnumerable по времени, в варианте IT — по нехватке памяти ). Я этот файл обработаю, но проблемы будут с экзотикой . ИМХО второе лучше.
S>Потом заказчик решит, что 5-10Гб текстового файла — слишком жестко для диска (или передачи по сети). И предложит зазиповать тексты. S>Вот тогда мы с IT изменим одну строчку, а тебе придется опять переписать все!
А чем ты гордишься ? Если бы ты сказал, что сумееешь вытащить эту строчку из архивированного файла без его распаковки — вот это было бы да! А так вы просто используете тот факт. что в .NET библиотеке есть (явно или неявно- не важно) этот распаковщик, а в С++ RTL его нет. Найду его — тоже в виде одной строчки напишу .
Ну а то, что библиотека .NET по своему составу очень даже неплохая — кто бы спорил. Ее бы неуправляемую версию сделать, да кое-что внутри переписать как следует, да внешний интерфейс несколько изменить (например, IEnumerable вместо (или хотя бы вместе) с методами, возвращающими коллекцию целиком) — вообще прелесть бы получилась
S>Но это все к теме о выдумывании условий, чтобы коню в вакууме скучно не было.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, samius, Вы писали:
PD>>>Хм... А стоит ли ? Обернуть, конечно, можно, но, честно говоря, сделать просто замену кода — работы на полчаса. Кстати, никакого IEnumerable пока что в варианте IT нет, это тоже надо делать. S>>Нет? А что там есть? Массив строк? Если честно, я его в точности не помню.
PD>ReadAllLines в буфер + Split
Вообще File.ReadAllLines читает строки последовательно из StreamReader-а и Split не делает и делать его незачем.
File.ReadAllLines("data.txt").Last();
Вернет последнюю строку если хватит памяти чтобы затолкать все строки. Единственная проблема ReadAllLines в том, что он читает все строки файла за раз и возвращает массив. Возвращал бы IEnumerable через yield return — не было бы проблем.
S>>>>У меня некоторые пробелы на тему кодировок. Я вот не уверен, что при чтении файла задом наперед, или какими-то кусками не с самого начала, можно гарантированно идентифицировать символы конца строки.
PD>Точно не кодируются ? В классическом Юникоде кодируются, только , естественно, wchar_t, а не char. А UTF-16 вроде как отличается лишь наличием суррогатных пар.
UTF-16 кодирует 16-битными словами как минимум. т.е. паттерн 0d0a будет означать единый символ.
S>>Потом заказчик решит, что 5-10Гб текстового файла — слишком жестко для диска (или передачи по сети). И предложит зазиповать тексты. S>>Вот тогда мы с IT изменим одну строчку, а тебе придется опять переписать все!
PD>А чем ты гордишься ? Если бы ты сказал, что сумееешь вытащить эту строчку из архивированного файла без его распаковки — вот это было бы да! А так вы просто используете тот факт. что в .NET библиотеке есть (явно или неявно- не важно) этот распаковщик, а в С++ RTL его нет. Найду его — тоже в виде одной строчки напишу .
К своему решению — нет, не получится. Если только не умеешь распаковывать зип с хвоста
PD>Ну а то, что библиотека .NET по своему составу очень даже неплохая — кто бы спорил.
нет, речь не о библиотеке .NET, а о высокоуровневых конструкциях vs чтению файла с конца.
Здравствуйте, samius, Вы писали:
S>Вообще File.ReadAllLines читает строки последовательно из StreamReader-а и Split не делает и делать его незачем.
Ну это к IT. Он там Split употребил.
S>Вернет последнюю строку если хватит памяти чтобы затолкать все строки. Единственная проблема ReadAllLines в том, что он читает все строки файла за раз и возвращает массив. Возвращал бы IEnumerable через yield return — не было бы проблем.
Это, кстати, хроническая болезнь .NET — вернем все вместо того, чтобы вернуть IEnumerable
S>UTF-16 кодирует 16-битными словами как минимум. т.е. паттерн 0d0a будет означать единый символ.
Гм. При чем тут 0d0a ? Там должно быть 000D 000A. В классическом Юникоде именно так. Раз символы двухбайтные. то и CR/LF тоже, они же тоже символы, причем из 0-127. которые совпадают с ASCII, только 2 байта.
S>>>Потом заказчик решит, что 5-10Гб текстового файла — слишком жестко для диска (или передачи по сети). И предложит зазиповать тексты. S>>>Вот тогда мы с IT изменим одну строчку, а тебе придется опять переписать все!
PD>>А чем ты гордишься ? Если бы ты сказал, что сумееешь вытащить эту строчку из архивированного файла без его распаковки — вот это было бы да! А так вы просто используете тот факт. что в .NET библиотеке есть (явно или неявно- не важно) этот распаковщик, а в С++ RTL его нет. Найду его — тоже в виде одной строчки напишу . S>К своему решению — нет, не получится. Если только не умеешь распаковывать зип с хвоста
Не понял. Ты будешь читать из GZipStream (так вроде) Но он же натравлен на файл, а значит, внутри себя будет распаковывать. Может, и не в файл, а в память (где он ее возьмет...). Ну а я найду функцию распаковки в файл, остальное как прежде.
PD>>Ну а то, что библиотека .NET по своему составу очень даже неплохая — кто бы спорил. S>нет, речь не о библиотеке .NET, а о высокоуровневых конструкциях vs чтению файла с конца.
Чтение файла хоть с начала, хоть с конца, хоть с середины , хоть как еще — дело вполне банальное. fseek в С++ или FileStream.Seek в .NET. А в конечном счете — SetFilePointer. В конечном счете — все одно и то же, потому как делает это ОС.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, samius, Вы писали:
S>>UTF-16 кодирует 16-битными словами как минимум. т.е. паттерн 0d0a будет означать единый символ.
PD>Гм. При чем тут 0d0a ? Там должно быть 000D 000A. В классическом Юникоде именно так. Раз символы двухбайтные. то и CR/LF тоже, они же тоже символы, причем из 0-127. которые совпадают с ASCII, только 2 байта.
А откуда мы об этом узнаем если в условии нет ничего о кодировке? В конце файла об этом не написано.
S>>>>Потом заказчик решит, что 5-10Гб текстового файла — слишком жестко для диска (или передачи по сети). И предложит зазиповать тексты. S>>>>Вот тогда мы с IT изменим одну строчку, а тебе придется опять переписать все!
PD>Не понял. Ты будешь читать из GZipStream (так вроде) Но он же натравлен на файл, а значит, внутри себя будет распаковывать. Может, и не в файл, а в память (где он ее возьмет...).
GZipStream натравливается на стрим же и является стримом. Т.е. это просто декоратор. Клиенту, читающему из стрима (в данном случае StreamReader-у) фиолетово, откуда читать, из FileStream или из GZipStream. Кстати, не везде в дотнете это фиолетово. Например, System.Drawing.Bitmap из GZipStream-а не умеет грузиться.
PD>Ну а я найду функцию распаковки в файл, остальное как прежде.
Оу. Так это чтобы прочитать последнюю строчку из зазипованного файла, нужно будет распаковать его, а это означает на диске должно быть адекватное свободное место... Да и долго!
Нет, разжимать в файл только для того чтобы прочитать последнюю строчку — плохая идея.
PD>Чтение файла хоть с начала, хоть с конца, хоть с середины , хоть как еще — дело вполне банальное. fseek в С++ или FileStream.Seek в .NET. А в конечном счете — SetFilePointer. В конечном счете — все одно и то же, потому как делает это ОС.
Да я не спорю. Речь о том, что высокоуровневое решение может оказаться гибче и быстрее при изменении требований, гораздо дешевле адаптироваться чем низкоуровневое.
Здравствуйте, samius, Вы писали:
S>А откуда мы об этом узнаем если в условии нет ничего о кодировке? В конце файла об этом не написано.
Верно. Но написано в начале. Придется еще пару байт из начала взять
S>>>>>Потом заказчик решит, что 5-10Гб текстового файла — слишком жестко для диска (или передачи по сети). И предложит зазиповать тексты. S>>>>>Вот тогда мы с IT изменим одну строчку, а тебе придется опять переписать все!
S>GZipStream натравливается на стрим же и является стримом. Т.е. это просто декоратор.
Это все на врехнем уровне. Не святой же дух там распакрвывает, а функция. Она создает там распакованный файл и подсовывает его. Я тоже могу сделать наследник от fstream, делающий внутри себя то же самое.
>Клиенту, читающему из стрима (в данном случае StreamReader-у) фиолетово, откуда читать, из FileStream или из GZipStream.
И мне тогда будет фиолетово. Ну согласись сам, не открыл же .NET что-то новое в плане доступа к архивам. Он просто внутри код содержит.
PD>>Ну а я найду функцию распаковки в файл, остальное как прежде. S>Оу. Так это чтобы прочитать последнюю строчку из зазипованного файла, нужно будет распаковать его, а это означает на диске должно быть адекватное свободное место... Да и долго!
А ты думаешь, твой GZIpStream вернет тебе эту строчку без распаковки ? Как это вообще можно сделать ?
S>Нет, разжимать в файл только для того чтобы прочитать последнюю строчку — плохая идея.
класс GZipStream. Выделено мной
public override IAsyncResult BeginRead(byte[] array, int offset, int count, AsyncCallback asyncCallback, object asyncState)
{
if (this.deflateStream == null)
{
throw new InvalidOperationException(SR.GetString("ObjectDisposed_StreamClosed"));
}
return this.deflateStream.BeginRead(array, offset, count, asyncCallback, asyncState);
}
Provides methods and properties for compressing and decompressing streams using the Deflate algorithm
Так что, как видишь, там внутри просто еще один — распакованный — поток. В файле или в памяти — не знаю, мне все равно.
Чудес не бывает.
PD>>Чтение файла хоть с начала, хоть с конца, хоть с середины , хоть как еще — дело вполне банальное. fseek в С++ или FileStream.Seek в .NET. А в конечном счете — SetFilePointer. В конечном счете — все одно и то же, потому как делает это ОС. S>Да я не спорю. Речь о том, что высокоуровневое решение может оказаться гибче и быстрее при изменении требований, гораздо дешевле адаптироваться чем низкоуровневое.
Черт его знает. Вот я взял в примере для IT и сделал так, что 0D на 0 заменяется, а файл при этом не страдает. Фишка — WRITECOPY механизм NT. Изменения коснулись 2 параметров, все. А с высокоуровневым решением придется копировать файл, это уже серьезнее.
Адаптировать проще при постройке из кирпичей, хотя строить из кирпичей намного медленнее. Захотел заказчик круглую стенку — будет круглая. А из крупных блоков не получится, если нет таких блоков.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, samius, Вы писали:
S>>GZipStream натравливается на стрим же и является стримом. Т.е. это просто декоратор.
PD>Это все на врехнем уровне. Не святой же дух там распакрвывает, а функция. Она создает там распакованный файл и подсовывает его. Я тоже могу сделать наследник от fstream, делающий внутри себя то же самое.
Именно святым духом!!! Никакой файл там не создается. BaseStream разжимается по мере чтения данных из декорирующего стрима, т.е. по мере того как StreamReader будет запрашивать очередную порцию чтобы заполнить буфер.
>>Клиенту, читающему из стрима (в данном случае StreamReader-у) фиолетово, откуда читать, из FileStream или из GZipStream.
PD>И мне тогда будет фиолетово. Ну согласись сам, не открыл же .NET что-то новое в плане доступа к архивам. Он просто внутри код содержит.
Соглашаюсь
S>>Оу. Так это чтобы прочитать последнюю строчку из зазипованного файла, нужно будет распаковать его, а это означает на диске должно быть адекватное свободное место... Да и долго!
PD>А ты думаешь, твой GZIpStream вернет тебе эту строчку без распаковки ? Как это вообще можно сделать ?
Нет, он мне все распакует, но накапливаться хозяйство не будет ни в файле, ни в памяти. Лишние строки соберет GC, а у StreamReader-а буфер фиксированный.
S>>Нет, разжимать в файл только для того чтобы прочитать последнюю строчку — плохая идея.
PD>класс GZipStream. Выделено мной
PD>
PD>public override IAsyncResult BeginRead(byte[] array, int offset, int count, AsyncCallback asyncCallback, object asyncState)
PD>{
PD> if (this.deflateStream == null)
PD> {
PD> throw new InvalidOperationException(SR.GetString("ObjectDisposed_StreamClosed"));
PD> }
PD> return this.deflateStream.BeginRead(array, offset, count, asyncCallback, asyncState);
PD>}
PD>
PD>Так что, как видишь, там внутри просто еще один — распакованный — поток. В файле или в памяти — не знаю, мне все равно.
DeflateStream делает основную работу. GZipStream — обертка. Распакованных данных нет в полном объеме. Они извлекаются по требованию Stream.Read(byte[], int, int).
PD>Чудес не бывает.
Да это не чудо а ловкость рук.
PD>Адаптировать проще при постройке из кирпичей, хотя строить из кирпичей намного медленнее. Захотел заказчик круглую стенку — будет круглая. А из крупных блоков не получится, если нет таких блоков.
S>Именно святым духом!!! Никакой файл там не создается. BaseStream разжимается по мере чтения данных из декорирующего стрима, т.е. по мере того как StreamReader будет запрашивать очередную порцию чтобы заполнить буфер.
Завтра посмотрю по рефлектору. Может, ты и прав. Но сути дела это не изменит — для последней строки все равно придется распаковать все.
>>>Клиенту, читающему из стрима (в данном случае StreamReader-у) фиолетово, откуда читать, из FileStream или из GZipStream.
S>Нет, он мне все распакует, но накапливаться хозяйство не будет ни в файле, ни в памяти. Лишние строки соберет GC, а у StreamReader-а буфер фиксированный.
Хм. Интересно. То есть при фиксированном буфере они решают проблему перехода от одной строки к другой ? При распаковке куска можно ведь и на середине строки оказаться...
S>>>Нет, разжимать в файл только для того чтобы прочитать последнюю строчку — плохая идея.
PD>>класс GZipStream. Выделено мной
PD>>
PD>>public override IAsyncResult BeginRead(byte[] array, int offset, int count, AsyncCallback asyncCallback, object asyncState)
PD>>{
PD>> if (this.deflateStream == null)
PD>> {
PD>> throw new InvalidOperationException(SR.GetString("ObjectDisposed_StreamClosed"));
PD>> }
PD>> return this.deflateStream.BeginRead(array, offset, count, asyncCallback, asyncState);
PD>>}
PD>>
PD>>Так что, как видишь, там внутри просто еще один — распакованный — поток. В файле или в памяти — не знаю, мне все равно. S>DeflateStream делает основную работу. GZipStream — обертка. Распакованных данных нет в полном объеме. Они извлекаются по требованию Stream.Read(byte[], int, int).
PD>>Чудес не бывает. S>Да это не чудо а ловкость рук.
PD>>Адаптировать проще при постройке из кирпичей, хотя строить из кирпичей намного медленнее. Захотел заказчик круглую стенку — будет круглая. А из крупных блоков не получится, если нет таких блоков.
S>Если нет блоков, то и спора нет.
Если и есть блоки , но не круглые. то и ничего не будет
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, samius, Вы писали:
S>>Нет, он мне все распакует, но накапливаться хозяйство не будет ни в файле, ни в памяти. Лишние строки соберет GC, а у StreamReader-а буфер фиксированный.
PD>Хм. Интересно. То есть при фиксированном буфере они решают проблему перехода от одной строки к другой ? При распаковке куска можно ведь и на середине строки оказаться...
Все немного не так. GZipStream подсаживается на FileStream, который создан над упакованным файлом и ведет себя как обычный стрим, но с ограничениями: только чтение и только последовательно (Никаких Seek, Length и пр.). Но операцию Read он обеспечивает с точностью как если бы мы читали напрямик из незажатого файла.
А проблему с серединой строк решает именно StreamReader, которому на вход подается стрим, чьи данные УЖЕ распакованы (точнее распаковываются по мере обращения к методу Read, но возвращаются распакованные).
Здравствуйте, samius, Вы писали:
S>Все немного не так. GZipStream подсаживается на FileStream, который создан над упакованным файлом и ведет себя как обычный стрим, но с ограничениями: только чтение и только последовательно (Никаких Seek, Length и пр.). Но операцию Read он обеспечивает с точностью как если бы мы читали напрямик из незажатого файла.
А... Ну тогда посмотри в Win API LZRead и иже с ними. Правда, я уже лет 10 их не использовал.
S>А проблему с серединой строк решает именно StreamReader, которому на вход подается стрим, чьи данные УЖЕ распакованы (точнее распаковываются по мере обращения к методу Read, но возвращаются распакованные).
Ладно, пора, я думаю в этой ветви .next = NULL делать
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Ты даже простую вещь не понимаешь. Взять 16 ядер — это не ускорение алгоритма. Это использование дополнительных ресурсов при неизменной (а то и хуже) скорости алгоритма. С таким же успехом можно предложить вместо Pentium 100 взять Pentium 4 3000 и сказать — мы ускорили в N0 раз. Ничего тут не ускоряется и нет никаких заслуг программиста в этом.
Это ты Гуглю расскажи, а то они за каким-то вместо одного большого компьютера и оптимизации алгоритма пользуют сотни тысяч средненьких серверов и затачивают свои алгоритмы под распределённую многопоточную среду.
Полировка алгоритма даст тебе в лучшем случае проценты, а наращивание железа даёт легко разы. Но алгоритм при этом должен быть заточен для работы в таких условиях. Буржуи такое свойство алгоритма называют иностранным словом scalability — масштабируемость, расширяемость. И это свойство именно алгоритма, а не дополнительных ресурсов, как ты изволил выразиться.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Давай прямо — для хотя бы 500 Мб файла — ты по-прежнему утверждаешь, что твое однострочное решение годится ? Да или нет ?
И да и нет. Первым делом я попробую написать версию GetAllLines через перечислитель. Это снимет проблему перегруза памяти, оставит исходный алгоритм практически в неизменном виде и даст мне универсальный экономичный способ построчной обработки файлов. Далее, если результат меня не удовлетворит я займусь менее универсальными оптимизациями типа обработки файла с конца.
Теперь я тебе задам вопрос. Давай прямо — для файла с заранее известным небольшим размером в пределах нескольких десятков килобайт и в местах не критичных по производительности — ты по-прежнему утверждаешь, что будешь заниматься выжиманием производительности? Да или нет ?
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Pavel Dvorkin, Вы писали:
F>>Функциональные требования описывают, что должна делать система.
PD>+1
Еще бы, это же бородатый баян. Карл Вигерс, "Разработка требований к ПО". Вам по букварю отвечают, а вы с букварем спорите.
>>Нефункциональные — как она должна это делать. То есть ограничения, накладываемые при выполнении данных функций.
PD>Эти ограничения тоже функциональны. Например, требование решать некую NP-полную задачу — это функциональное ? А если это требуют делать при N=1000, это уже нефункционально ? Сначала напишешь алгоритм полного перебора, а потом скажешь — ой, извините, ответ вы получите в 50 веке
Требование решить NP полную задачу — функциональное, N = 1000 это допустимые входные данные. И если мне не сказали, что допустимые входные данные такие, то я волен решать ее как мне захочется.
PD>Еще раз. Быстродействие входит в число функциональных требований. При недостаточно высоком — решение просто не рассматривается.
Не хотите статью на rsdn написать? Это новое слово в разработке требований.
PD>Вот представь себе ПО управления самолетом. Если оно будет реагировать на изменение обстановки очень медленно — его просто выкинут сразу. В функциональные требования такого ПО входит — реакция не медленнее, чем за такое-то время. Более того. Если окажется, что удовлетворить другим требованиям за это время не удастся — я вполне могу допустить, что часть других требований будет снята или ослаблена. А время — нет, потому что если реакция будет медленнее, чем ..., то управлять уже будет нечем.
Производительность входит в нефункциональные требования.
PD>У меня, конечно, не самолетное ПО, но идея та же самая. Риски там, правда, нулевые, ничего не грохнется, но недостаточно быстрые решения не рассматриваются. А для достаточно быстрого решения всегда макисма такая — сделайте еще быстрее, если можете.
И что, всегда требования производительности более важны, чем функции системы? Ну, типа, если есть хоть малейший шанс увеличить производительность, то мы ее увеличиваем, а не добавляем новые фичи?
Здравствуйте, IT, Вы писали:
IT>Полировка алгоритма даст тебе в лучшем случае проценты, а наращивание железа даёт легко разы. Но алгоритм при этом должен быть заточен для работы в таких условиях. Буржуи такое свойство алгоритма называют иностранным словом scalability — масштабируемость, расширяемость. И это свойство именно алгоритма, а не дополнительных ресурсов, как ты изволил выразиться.
Не знаю, что там буржуи делают, но если ты увеличиваешь ресурсы (железо и т.д.), то это называется именно увеличением ресурсов, а не оптимизацией программы. Покупая новые ресурсы, можно все что угодно усилить.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Давай прямо — для хотя бы 500 Мб файла — ты по-прежнему утверждаешь, что твое однострочное решение годится ? Да или нет ?
IT>И да и нет. Первым делом я попробую написать версию GetAllLines через перечислитель.
А зачем это делать-то ? Есть же просто ReadLine, вызывай ее в цикле до конца файла.
>Это снимет проблему перегруза памяти
так while — ReadLine это и так даст.
>оставит исходный алгоритм практически в неизменном виде
Во имя чего ?
>и даст мне универсальный экономичный способ построчной обработки файлов. Далее, если результат меня не удовлетворит я займусь менее универсальными оптимизациями типа обработки файла с конца.
Вот с этим соглашусь. И если бы ты с самого начала написал бы что-то вроде "при небольшом файле можно ReadAllLines, а иначе надо...", я бы просто сразу согласился, и не было бы темы дискуссии.
IT>Теперь я тебе задам вопрос. Давай прямо — для файла с заранее известным небольшим размером в пределах нескольких десятков килобайт и в местах не критичных по производительности — ты по-прежнему утверждаешь, что будешь заниматься выжиманием производительности? Да или нет ?
Конечно, нет, даже странно такой вопрос от тебя получить. Я же об этом сто раз писал. Вот, например
PD>Еще раз — истина конкретна. Под 1 Кб — нечего огород городить. Под 100 Мб — самый раз. Под 100 Гб — да, лучше иначе.
И в других местах писал, просто искать лень. Ты берешься опровергать мои высказывания, а ведь ты даже не поянл мою концепцию. А она проста
Я не сторонник универсальных решений. Я за то, чтобы решения принимались с учетом конкретной ситуации. Одна и та же задача (тот же парсинг файла, к примеру) может потребовать разных решений в зависимости от объема обрабатываемых данных, возможности или невозможности распараллеливания, требований к памяти, времени и т.д. И именно с учетом всех этих факторов ее и надо решать.
Да и вообще, если уж на то пошло
string GetLastLine(string fileName)
{
// ...
}
Вот тебе универсальное решение . Внутренности — по ситуации и задаче. Хочешь написать там ReadAllLines + Split — пиши. Надо иначе — перепишем ее иначе, остальной код никак не пострадает, даже если там внутри сначала появится энумератор, потом аккумулятор, а в конечном итоге трансформатор . Из-за чего шум-то весь ? Из-за чего такая гордость однострочным 10-секундным решением ? Только из-за того, что я еще одну строку написал и две фигурные скобки ?