Многопоточная поиск и замена в ТХТ файле. Возможно?

toxass

Client
Регистрация
18.03.2010
Сообщения
280
Благодарностей
12
Баллы
18
Есть ТХТ файл с разным контентом, необходимо найти и заменить порядка 100к строк.

Подскажите самый быстрый и многопоточный алгоритм решения этой задачи с помощью Зеннопостра.
 

myweb101

Client
Регистрация
29.04.2013
Сообщения
175
Благодарностей
30
Баллы
28
Разделить файл на части, запустить замену во многопотоке другим шаблоном.
 

surrealmix

Client
Регистрация
07.03.2013
Сообщения
715
Благодарностей
409
Баллы
63
Есть ТХТ файл с разным контентом, необходимо найти и заменить порядка 100к строк.

Подскажите самый быстрый и многопоточный алгоритм решения этой задачи с помощью Зеннопостра.
Нечетко описана задача.
 

ZennoScript

Moderator
Регистрация
04.03.2011
Сообщения
4 450
Благодарностей
1 885
Баллы
113
На самом деле 100к - это не кретичная цифра. Опишите подробнее, что именно Вам нужно. Не думаю, что эта процедура займёт много времени даже в один поток.
 

toxass

Client
Регистрация
18.03.2010
Сообщения
280
Благодарностей
12
Баллы
18
На самом деле 100к - это не кретичная цифра. Опишите подробнее, что именно Вам нужно. Не думаю, что эта процедура займёт много времени даже в один поток.
Конкретно. Файл, в котором нужно делать замены весит 300мб, в нем новости с разными ссылками, эти ссылки мне и нужно заменить на свои из заранее подготовленного списка: Сссылку1 заменить на Ссылку2 и так 100к строк. В 1 поток делает очень долго. Разбивать не могу.
 

Geograph

Client
Регистрация
16.02.2014
Сообщения
209
Благодарностей
114
Баллы
43
Конкретно. Файл, в котором нужно делать замены весит 300мб, в нем новости с разными ссылками, эти ссылки мне и нужно заменить на свои из заранее подготовленного списка: Сссылку1 заменить на Ссылку2 и так 100к строк. В 1 поток делает очень долго. Разбивать не могу.
Насколько я знаю, многопоток тут не поможет, т.к. вы упрётесь в скорость работы диска и будет не быстрее, чем при однопотоке
 

ZennoScript

Moderator
Регистрация
04.03.2011
Сообщения
4 450
Благодарностей
1 885
Баллы
113
Тут наверное проще будет сразу выгрузить весь файл в память, выполнить в нём замены и потом записать назад.
Памяти конечно отожрёт прилично сразу.
Делать такое многопотоком точно не вариант, будет только хуже.
Как вариант, если эти новости каким то образом отделяются одна от другой - брать их отдельно с удалением, обрабатывать и записывать в новый файл. Тогда можно и несколько потоков использовать.
 

toxass

Client
Регистрация
18.03.2010
Сообщения
280
Благодарностей
12
Баллы
18
Тут наверное проще будет сразу выгрузить весь файл в память, выполнить в нём замены и потом записать назад.
Памяти конечно отожрёт прилично сразу.
Делать такое многопотоком точно не вариант, будет только хуже.
Как вариант, если эти новости каким то образом отделяются одна от другой - брать их отдельно с удалением, обрабатывать и записывать в новый файл. Тогда можно и несколько потоков использовать.
ОЗУ 32 ГБ, но вот удалять тоже нельзя. Выходит только ждать?
 

surrealmix

Client
Регистрация
07.03.2013
Сообщения
715
Благодарностей
409
Баллы
63
Конкретно. Файл, в котором нужно делать замены весит 300мб, в нем новости с разными ссылками, эти ссылки мне и нужно заменить на свои из заранее подготовленного списка: Сссылку1 заменить на Ссылку2 и так 100к строк. В 1 поток делает очень долго. Разбивать не могу.
В 1 поток файл в 905Mb обрабатывает за 4-5 минут:

C#:
//<a href="https://google.com">Click here</a>
var file_1 = @"F:\Tests\100k.txt";

//Hello from Zenno <a href="https://yandex.ru">Yandex Company</a> this is end of sentence
var file_2 = @"F:\Tests\10kk.txt"; //905mb

//Hello from Zenno <a href="https://google.com">Click here</a> this is end of sentence
var file_3 = @"F:\Tests\Result.txt";

//Регулярка для замены
var regex = new Regex(@"<a\ .*?</a>");

var links = File.ReadLines(file_1, Encoding.UTF8).ToList();
var lines = File.ReadLines(file_2, Encoding.UTF8);


var fs = new FileStream(file_3, FileMode.OpenOrCreate, FileAccess.Write);
var sw = new StreamWriter(fs, Encoding.UTF8);
sw.AutoFlush = true;

foreach(string line in lines)
{
    var changedStr = line;
    var mCount = regex.Matches(changedStr).Count;
   
    for(int i=0; i< mCount; i++)
    {
        if(links.Count > 0)
        {
            var link = links.ElementAt(0);
            links.RemoveAt(0);
            changedStr = regex.Replace(changedStr, link, i+1);
        }
    }   
    sw.WriteLine(changedStr);
}

sw.Close();
fs.Close();
 

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
В 1 поток файл в 905Mb обрабатывает за 4-5 минут:

C#:
//<a href="https://google.com">Click here</a>
var file_1 = @"F:\Tests\100k.txt";

//Hello from Zenno <a href="https://yandex.ru">Yandex Company</a> this is end of sentence
var file_2 = @"F:\Tests\10kk.txt"; //905mb

//Hello from Zenno <a href="https://google.com">Click here</a> this is end of sentence
var file_3 = @"F:\Tests\Result.txt";

//Регулярка для замены
var regex = new Regex(@"<a\ .*?</a>");

var links = File.ReadLines(file_1, Encoding.UTF8).ToList();
var lines = File.ReadLines(file_2, Encoding.UTF8);


var fs = new FileStream(file_3, FileMode.OpenOrCreate, FileAccess.Write);
var sw = new StreamWriter(fs, Encoding.UTF8);
sw.AutoFlush = true;

foreach(string line in lines)
{
    var changedStr = line;
    var mCount = regex.Matches(changedStr).Count;
 
    for(int i=0; i< mCount; i++)
    {
        if(links.Count > 0)
        {
            var link = links.ElementAt(0);
            links.RemoveAt(0);
            changedStr = regex.Replace(changedStr, link, i+1);
        }
    } 
    sw.WriteLine(changedStr);
}

sw.Close();
fs.Close();
Собирай финальный список в 1 и записывай полностью, а то у тебя все время идут накладные нагрузки на отправку драйверу жесткого диска маленьких данных на запись с большим буффером, вот ты и записываешь их медленно. Плюс можно использовать Parallel.Foreach
Также не стоит удалять данные с листа, а легче их записывать в очередь (или защищенную коллекцию очереди при Parallel.Foreach), так как листы работают медленнее коллекций очередей и стеков
 

Кто просматривает тему: (Всего: 2, Пользователи: 0, Гости: 2)