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

  • Автор темы Автор темы toxass
  • Дата начала Дата начала

toxass

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

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

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

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

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

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

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

Также подойдет вариант взять случайный вариант по домену (стандартный функционал тоже на долго зависает, я проверил).
 
Я думаю тебе надо разделить на пачки типа у тебя 1 250 000 ты берешь первые 1000 ну и т.д
Мне помог такой метод когда я импорт с 1С делал на сайт , беру все махом висит беру кусками в лет
 
Версия: 5.3

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

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

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

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

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

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

Также подойдет вариант взять случайный вариант по домену (стандартный функционал тоже на долго зависает, я проверил).
а последнее не проверял?
 
Попробуйте работать с каждой строкой отдельно - 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
Попробуйте работать с каждой строкой отдельно - 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
ничего не понял, но как всегда очень интересно))))))
 
Спасибо
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

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