Я не спорю, я просто имел ввиду немного другое. Критическая секция и TThread.Synchronize это совершенно разные вещи, сравнивать их беззсмысленно и если учесть, то что добавление в очередь идет через ту же самую критическую секцию, так же используются объекты ядра(событие) - естественно скорость меньше.
я в курсе (внезапно) просто ты привел пример из своей практики, а я привел 2 момента которые говорят как раз о том, что это совсем другой случай. ps кстати я когда работал в дельфи, поначалу тоже записывал в лог на форме сразу через Synchronize. потом перешел на виндовые сообщения - стало побыстрее. но в итоге таки начал юзать буффер а сбрасывать его в лог по таймеру. оказалось что это не инди такая тормозная библиотека, а тупо неоптимизированная работа с ГУИ была нагрузка на CPU сразу стала заметно меньше. но тут, повторюсь, совсем не тот случай.
а вот мне интересно сторонники "буфферизации" забыли что буффер то тоже общий, а значит его тоже надо оборачивать в крит. секцию? 100 строк, без буффера: 100 lock'ов, 100 вызовов WriteLine, одна КС (на файл), потери данных нет с буффером: 100 локов для буффера, 1 лок для файла, запись 100 строк (тест показал что разницы особой нету), 2 КС (одна для буффера, одна для файла), потенциальная потеря данных, усложнение кода. так в чем профит-то?
Критическая секция для файла? Зачем? Где ты видишь потенциальную потерю данных и усложнение кода? При буферизации все строки могут записаться за 1 раз, в то время как без буферизации каждая строка будет записываться отдельно.
а что с файлом будет работать какой-то определенный поток? Если часть данных хранится в памяти, то при внезапной остановке программы эта часть может просто потеряться. Причин этому может быть множество. N времени зря брутили. с буффером кода больше получится. разве нет? а могут и не записаться. и? алсо, эта разница в 2 миллисекунды которую показал тест, запросто улетучивается засчет расходов на обслуживание буффера. что-то я опять не заметил в чем профит.
Критическая секция нужна только для объекта, который выполняет вывод с буферизацией и ни для чего больше. С чего случаться внезапной остановке? Если все же произойдет что то аварийное, то в худшем случае будет утеряно 4-8 Кб. данных (размер буфера). Ты не знаешь, что в коде, который ты написал выше (https://forum.antichat.ru/showpost.php?p=3341500&postcount=6) выполняется вывод с буферизацией? Нечего сказать. В обоих случаях используется буферизация.
свет выключили, необработанное исключение в программе, переполнение диска. да мало ли чего. причин разных могут быть десятки. а ты на авось надеешься. у ПО смысл такой - обработка информации. И сохранение результатов своей работы. если программа не может гарантировать сохранение, но при этом она с буффером - это говнопрограмма. если представить что средняя длина пароля в однобайтовой кодировке 10 байт, то в 8 кб поместится примерно 680 паролей. а это может быть результатом целого часа работы брутера. а за час может многое произойти. даже конец света. тот тест имел совсем другой смысл. тест ну вот написал тест в многопоточном режиме. работа с сетью эмулируется при помощи Thread.Sleep(). один поток записывает 1 пароль в секунду. создаем временный проект в VS, копируем, вставляем, запускаем без отладки. сравниваем среднее количество тиков на вызовы Write(password). сравниваем простоту реализации классов представляющих разный метод сохранения паролей. потом объясняем мне смысл использования буффера. у меня выдает одинаковую производительность на обоих способах. но с моим способом получаем простоту и стабильность, а с твоим - переусложнённость и нестабильность.
Для начала должен сказать, что своих способов я не приводил, так что "переусложнённость и нестабильность" - это только то, что написал ты и как ты это понимаешь. Свет могут выключить и тогда, когда программа будет записывать данные на винт, то есть от этого не застрахован ни в каком случае. Да, когда буферизация не используется, то маловероятно что то потерять. Вообще для брутфорса буферизация результатов не столь важна, можно и без нее обойтись. Но дело в том, что у тебя не правильное понимание термина буферизации. Ты создаешь какие то дополнительные List'ы и синхронизируешь их, это неправильно. Зачем все это делать и зачем так извращаться, если StreamWriter делает буферизацию за тебя, даже большее: по умолчанию он уже записывает данные с буферизацией! То есть в том примере, который ты привел, оба класса используют буферизацию Даже больше: класс PasswordWriterWithBuffer использует ненужную двойную буферизацию. Посмотрим на пример работы твоего кода: Code: Брут с буффером начался. Нажмите S для останова s Записано 1459 паролей. Среднее количество тактов на вызов Write = 7 Брут без буффера начался. Нажмите S для останова s Записано 1381 паролей. Среднее количество тактов на вызов Write = 7 Теперь все же отключим буферизацию в твоем классе PasswordWriterBufferSucks. Для этого напишем такой конструктор Code: public PasswordWriterBufferSucks() { writer.AutoFlush = true; } И смотрим на вывод программы: Code: Брут с буффером начался. Нажмите S для останова s Записано 1633 паролей. Среднее количество тактов на вызов Write = 10 Брут без буффера начался. Нажмите S для останова s Записано 1762 паролей. Среднее количество тактов на вызов Write = 101 Осталось только процитировать:
а ну да, я опять забыл про AutoFlush погонял с разным размером буфера. даже с 12 байтами разница в десятки раз. увеличение буфера не дает практически прироста производительности. 12 байтjd это примерно 1 строка. следовательно это почти равнозначно работе вообще без буфера. верно? смысла ставить буфер 4092 вообще ноль - 12 тиков при 12 байтах и 11 при 4092 байтах. а значит, StreamWriter попросту не оптимизирован на построчную запись. и дело вовсе не в буферизации. надо глянуть исходники. в-общем, я буду выяснять, почему так происходит. почему, мать его, StreamWriter при AutoFlush = true записывает по одной строке дольше, чем при AutoFlush = false
Тогда почему запись по 10 строк занимает в 50 раз меньше времени, чем запись по одной? Не бросается в глаза непропорциональность? И почему ты настаиваешь на размере буфера 4кб и 8кб, если и 128 байт вполне достаточно, при минимальных потерях данных?
Если в обоих случаях используется буферизация, то время записи должно быть примерно одинаковое. Если говорить о производительности, то лучше чтобы размер буфера равнялся размеру кластера диска (обычно 4 или 8 кб.). Но и 128 кб. тоже неплохо, только операций вывода будет больше.