Слишком долго идет обработка REGEX и как быть?

toxass

Client
Регистрация
18.03.2010
Сообщения
280
Благодарностей
12
Баллы
18
Версия: 5.3

Стоит задача брать из списка все варианты ссылок по домену, всего в списке 1 250 000 строк.

Загружаю список всех ссылок в переменную, это быстро.

Затем беру из другого списка домен, тоже быстро.

Теперь использую регулярку:
.*domain.com.* - что брать «все»

И на этом этапе жду 3-5 минут, пока он соберет из переменной в 1 250 000 строк ссылки с указанным доменом. Как это ускорить?

Проверил, если брать не «все», а «первое», получаю практически мгновенный результат, но это не подходить, ведь мне нужны все результаты по домену.

Также подойдет вариант взять случайный вариант по домену (стандартный функционал тоже на долго зависает, я проверил).
 

biryukovm

Client
Регистрация
19.05.2019
Сообщения
147
Благодарностей
10
Баллы
18
Я думаю тебе надо разделить на пачки типа у тебя 1 250 000 ты берешь первые 1000 ну и т.д
Мне помог такой метод когда я импорт с 1С делал на сайт , беру все махом висит беру кусками в лет
 

doc

Client
Регистрация
30.03.2012
Сообщения
8 685
Благодарностей
4 640
Баллы
113
Версия: 5.3

Стоит задача брать из списка все варианты ссылок по домену, всего в списке 1 250 000 строк.

Загружаю список всех ссылок в переменную, это быстро.

Затем беру из другого списка домен, тоже быстро.

Теперь использую регулярку:
.*domain.com.* - что брать «все»

И на этом этапе жду 3-5 минут, пока он соберет из переменной в 1 250 000 строк ссылки с указанным доменом. Как это ускорить?

Проверил, если брать не «все», а «первое», получаю практически мгновенный результат, но это не подходить, ведь мне нужны все результаты по домену.

Также подойдет вариант взять случайный вариант по домену (стандартный функционал тоже на долго зависает, я проверил).
а последнее не проверял?
 

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 781
Благодарностей
2 441
Баллы
113
Попробуйте работать с каждой строкой отдельно - 2 000 000 строк отрабатывать должно быстрее.
Пример кода вместе с измерениями моделирующий поставленную Вами задачу отрабатывает за 6 секунд, и это можно ещё ускорить если проводить обработку в многопоточном режиме.
C#:
List<string> in_data = new List<string>(); // Создали список
string[] temp = new[]{"+++domain.com---","+++site.com---","+++www.com---","+++wap.com---"}; // Случайный список значений

System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); // Создали таймер
timer.Start(); //Запустили отсчёт
for(int i=0;i<2000000; i++) in_data.AddRange(temp.OrderBy(x=>Guid.NewGuid()).Take(1).ToArray()); // Заполнили список случайными значениями
timer.Stop();  // Остановили таймер
string message = string.Format("Количество строк вход: {1} {0:mm}:{0:ss}.{0:ff}", timer.Elapsed, in_data.Count); // Привели значение к желаемому виду
project.SendInfoToLog(message); // Вывели на экран

timer.Restart(); // Начали измерение времени сначала
List<string> out_data = new List<string>(); // Создали список для результата
for(int i=0;i<in_data.Count; i++) {
    string temp_line =in_data[i]; // Сохранили строчку во временную переменную
    if(!string.IsNullOrEmpty(temp_line)) { // Убедились что строка не пустая, чтобы не тратить на нее время
        string temp_data = Regex.Match(temp_line, @".*domain.com.*").Value;      // Получили значение регуляркой
        if(!string.IsNullOrEmpty(temp_data)) out_data.Add(temp_data); // Добавили результат в список
    }
}
timer.Stop();  // Остановили таймер
message = string.Format("Количество строк выход: {1} {0:mm}:{0:ss}.{0:ff}", timer.Elapsed, out_data.Count); // Привели значение к желаемому виду
project.SendInfoToLog(message); // Вывели на экран
52966


Применяем многопоток для обработки данных - и видим, что тех самых 2 000 000 строчек мы уже проходим не за 6 секунд, а за 2.
C#:
List<string> in_data = new List<string>(); // Создали список
string[] temp = new[]{"+++domain.com---","+++site.com---","+++www.com---","+++wap.com---"}; // Случайный список значений

System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); // Создали таймер
timer.Start(); //Запустили отсчёт
for(int i=0;i<2000000; i++) in_data.AddRange(temp.OrderBy(x=>Guid.NewGuid()).Take(1).ToArray()); // Заполнили список случайными значениями
timer.Stop();  // Остановили таймер
string message = string.Format("Количество строк вход: {1} {0:mm}:{0:ss}.{0:ff}", timer.Elapsed, in_data.Count); // Привели значение к желаемому виду
project.SendInfoToLog(message); // Вывели на экран

timer.Restart();
List<string> out_data = new List<string>(); // Создали список

out_data.AddRange(in_data.AsParallel().Select(y => Regex.Match(y, @".*domain.com.*").Value).Where(x =>!string.IsNullOrEmpty(x))); // Параллельная обработка
timer.Stop();  // Остановили таймер
message = string.Format("Количество строк выход: {1} {0:mm}:{0:ss}.{0:ff}", timer.Elapsed, out_data.Count); // Привели значение к желаемому виду
project.SendInfoToLog(message); // Вывели на экран
52967
 
Последнее редактирование:
  • Спасибо
Реакции: kagorec

malysh

Client
Регистрация
27.07.2017
Сообщения
420
Благодарностей
55
Баллы
28
Попробуйте работать с каждой строкой отдельно - 2 000 000 строк отрабатывать должно быстрее.
Пример кода вместе с измерениями моделирующий поставленную Вами задачу отрабатывает за 6 секунд, и это можно ещё ускорить если проводить обработку в многопоточном режиме.
C#:
List<string> in_data = new List<string>(); // Создали список
string[] temp = new[]{"+++domain.com---","+++site.com---","+++www.com---","+++wap.com---"}; // Случайный список значений

System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); // Создали таймер
timer.Start(); //Запустили отсчёт
for(int i=0;i<2000000; i++) in_data.AddRange(temp.OrderBy(x=>Guid.NewGuid()).Take(1).ToArray()); // Заполнили список случайными значениями
timer.Stop();  // Остановили таймер
string message = string.Format("Количество строк вход: {1} {0:mm}:{0:ss}.{0:ff}", timer.Elapsed, in_data.Count); // Привели значение к желаемому виду
project.SendInfoToLog(message); // Вывели на экран

timer.Restart(); // Начали измерение времени сначала
List<string> out_data = new List<string>(); // Создали список для результата
for(int i=0;i<in_data.Count; i++) {
    string temp_line =in_data[i]; // Сохранили строчку во временную переменную
    if(!string.IsNullOrEmpty(temp_line)) { // Убедились что строка не пустая, чтобы не тратить на нее время
        string temp_data = Regex.Match(temp_line, @".*domain.com.*").Value;      // Получили значение регуляркой
        if(!string.IsNullOrEmpty(temp_data)) out_data.Add(temp_data); // Добавили результат в список
    }
}
timer.Stop();  // Остановили таймер
message = string.Format("Количество строк выход: {1} {0:mm}:{0:ss}.{0:ff}", timer.Elapsed, out_data.Count); // Привели значение к желаемому виду
project.SendInfoToLog(message); // Вывели на экран
Посмотреть вложение 52966


Применяем многопоток для обработки данных - и видим, что тех самых 2 000 000 строчек мы уже проходим не за 6 секунд, а за 2.
C#:
List<string> in_data = new List<string>(); // Создали список
string[] temp = new[]{"+++domain.com---","+++site.com---","+++www.com---","+++wap.com---"}; // Случайный список значений

System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); // Создали таймер
timer.Start(); //Запустили отсчёт
for(int i=0;i<2000000; i++) in_data.AddRange(temp.OrderBy(x=>Guid.NewGuid()).Take(1).ToArray()); // Заполнили список случайными значениями
timer.Stop();  // Остановили таймер
string message = string.Format("Количество строк вход: {1} {0:mm}:{0:ss}.{0:ff}", timer.Elapsed, in_data.Count); // Привели значение к желаемому виду
project.SendInfoToLog(message); // Вывели на экран

timer.Restart();
List<string> out_data = new List<string>(); // Создали список

out_data.AddRange(in_data.AsParallel().Select(y => Regex.Match(y, @".*domain.com.*").Value).Where(x =>!string.IsNullOrEmpty(x))); // Параллельная обработка
timer.Stop();  // Остановили таймер
message = string.Format("Количество строк выход: {1} {0:mm}:{0:ss}.{0:ff}", timer.Elapsed, out_data.Count); // Привели значение к желаемому виду
project.SendInfoToLog(message); // Вывели на экран
Посмотреть вложение 52967
ничего не понял, но как всегда очень интересно))))))
 

toxass

Client
Регистрация
18.03.2010
Сообщения
280
Благодарностей
12
Баллы
18
Спасибо
Dimionix


за крутой вариант, скорость космос:

C#:
IZennoList sourceList = project.Lists["SourceList"]; // исходный список
IZennoList destList = project.Lists["DestList"]; // список назначения
string domain = project.Variables["domain"].Value; // переменная с доменом

lock (SyncObjects.ListSyncer) {
    List<string> tempList = sourceList.ToList();
    tempList.RemoveAll(s => !s.Contains(domain));
    destList.AddRange(tempList);
}
 
  • Спасибо
Реакции: Dimionix и Sergodjan

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