gifts2017

Строка в число (Обычный способ и способ, основанный на регулярных выражениях). Тестирование скорости выполнения на больших данных

Опубликовал Петр Лунегов (pvlunegov) в раздел Программирование - Практика программирования

В данной обработке используется 2 способа выделения массива чисел из заданной строки любого размера.
Один способ использует обычный перебор символом и выделение символов цифр из строки.
Второй способ использует регулярные выражения.
На разном оборудовании разные способы выдают разное время выполнения.
Для внедрения в конфигурацию одного из способов может потребоваться протестировать время выполнения (миллисекунд) и сравнить.
Именно для этих целей предназначена данная простая обработка.

В моей практике програмиста понадобился способ получения массива чисел из строки.

Пришлось писать функцию.

Условия задачи:

  1. Разложение строки в массив чисел выполнять НА КЛИЕНТЕ дял уменьшения нагрузки на сервер.
  2. Алгоритм должен быть МАКСИМАЛЬНО БЫСТРЫМ.

Для этих целей я написал простую обработку, реализующую 2 способа обработки неограниченной строки в число. Точнее, в массив чисел:

  1. Один способ использует обычный перебор символом и выделение символов цифр из строки.
  2. Второй способ использует регулярные выражения.

В обработке есть 4 команды, позволяющие протестировать 2 способа разложения НА СЕРВЕРЕ, НА КЛИЕНТЕ.

Таким образом, можно оценить разницу скоростей выполнения.

 

Заранее невозможно предсказать скорость выполнения данной задачи. ПОЧЕМУ:

1. При выполнении на сервере время выполнения зависит от:

  • Скорости работы памяти на сервере
  • Скорости работы локальной сети (при больших объемах данных). Например, попробуйте загнать в обработку 1000 строк и посмотрите на скорость выполнения!
  • От нагрузки на сеть и сервер в текущий момент времени.

2. При выполнении обработки на клиенте время выполнения зависит от:

  • скорости работы локальной памяти на компьютере
  • мощности процессора на локальном компе и т.п.

Поэтому по сути В ОБЩЕМ случае невозвожно предложить тот или иной способ из 4-х предложенных в данной обработке!

Тестируйте на каждом отдельном компьютере и сервере, на больших данных!

Удачи!

 

P.S. Напоследок немного кода:

1.  Замер времени выполнения кода в миллисекундах, секундах, ну можно еще минутах, часах и т.п.

	Сообщить("Начало замера времени: получение массива чисел из строки. Регулярные выражения. На Сервере", СтатусСообщения.Важное);	
 	НачалоТочноеВремяМиллисекунды = ТекущаяУниверсальнаяДатаВМиллисекундах();

	... исполняемый код

	ОкончаниеТочноеВремяМиллисекунды = ТекущаяУниверсальнаяДатаВМиллисекундах();		
	
	ВремяВыполненияВМиллисекундах = ОкончаниеТочноеВремяМиллисекунды - НачалоТочноеВремяМиллисекунды;
	ВремяРаботыСекунд = цел(ВремяВыполненияВМиллисекундах/1000);
	ФорматВремени = "ДЛФ=В";
	
	ВремяВыполнения = "Окончание замера времени. Время работы (секунд:миллисекунд): "+ФОРМАТ(ВремяРаботыСекунд,"ДЛФ=T")
2. Неограниченная Строка в массив чисел, способ №1
Функция НайтиЧислаВСтрокеОбычныйСпособНаСервере(Строка)
	// для примера возьмем такую строку	Строка = "ыдлвапдлцоук234124ывпо555епрст1я"
	Сообщить("Начало замера времени: получение массива чисел из строки. Обычный способ. На Сервере", СтатусСообщения.Важное);	
	НачалоТочноеВремяМиллисекунды = ТекущаяУниверсальнаяДатаВМиллисекундах();
	
	МассивЧисел = Новый Массив; // сюда поместим все найденные числа. В данном примере в массив должно попасть 3 числа: 234224, 555 и 1
	
	СтрокаЧисел = "";
	
	Для Индекс = 1 По СтрДлина(Строка) Цикл
		
		Символ = Сред(Строка, Индекс, 1); // Перебираем все сиволы из нашей строки
		
		Если КодСимвола(Символ) >= 48 И КодСимвола(Символ) <= 57 Тогда // Код нуля - 48, код 9-ки - 57
			СтрокаЧисел = СтрокаЧисел + Символ;
		ИначеЕсли СтрДлина(СтрокаЧисел) > 0 Тогда
			МассивЧисел.Добавить(Число(СтрокаЧисел));
			СтрокаЧисел = "";
		КонецЕсли;
		
	КонецЦикла;
	Если СтрДлина(СтрокаЧисел)>0 Тогда
		МассивЧисел.Добавить(Число(СтрокаЧисел));
	КонецЕсли;
	
	ОкончаниеТочноеВремяМиллисекунды = ТекущаяУниверсальнаяДатаВМиллисекундах();		
	
	ВремяВыполненияВМиллисекундах = ОкончаниеТочноеВремяМиллисекунды - НачалоТочноеВремяМиллисекунды;
	ВремяРаботыСекунд = цел(ВремяВыполненияВМиллисекундах/1000);
	ФорматВремени = "ДЛФ=В";
	
	ВремяВыполнения = "Окончание замера времени. Время работы (секунд:миллисекунд): "+ФОРМАТ(ВремяРаботыСекунд,"ДЛФ=T")+":"+Формат(ВремяВыполненияВМиллисекундах - ВремяРаботыСекунд*1000, "ЧЦ=3; ЧН=000; ЧВН=");
	Сообщить(ВремяВыполнения, СтатусСообщения.Важное);						
	
	Возврат МассивЧисел; // Из строки в начале функции, получается массив: 234224, 555 и 1
КонецФункции
3. Неограниченная Строка в массив чисел. Способ №2. Регулярные выражения.
Функция НайтиЧислаВСтрокеРегулярныеВыраженияНаСервере(Строка)
	// для примера возьмем такую строку	Строка = "ыдлвапдлцоук234124ывпо555епрст1я"
	Сообщить("Начало замера времени: получение массива чисел из строки. Регулярные выражения. На Сервере", СтатусСообщения.Важное);	
 	НачалоТочноеВремяМиллисекунды = ТекущаяУниверсальнаяДатаВМиллисекундах();
 	МассивЧисел = Новый Массив; // сюда поместим все найденные числа. В данном примере в массив должно попасть 3 числа: 234224, 555 и 1
	
	RegExp = Новый COMОбъект("VBScript.RegExp"); 
	RegExp.IgnoreCase = Истина; 
	RegExp.Global = Истина; 
	RegExp.MultiLine = Ложь; 
	RegExp.Pattern = "\d+";
	Matches= RegExp.Execute(Строка); 
	Для Сч = 0 по Matches.Count()-1 Цикл
		Match = Matches.Item(Сч);
		//Сообщить("" + Match.Value+ "");
		МассивЧисел.Добавить(Число(Match.Value));
		Submatches = Match.Submatches;
		Для сч1=0 по Submatches.Count()-1 Цикл
			Submatch = Submatches.Item(Сч1);
			МассивЧисел.Добавить(Число(Submatch));
		КонецЦикла;
	КонецЦикла;
	ОкончаниеТочноеВремяМиллисекунды = ТекущаяУниверсальнаяДатаВМиллисекундах();		
	
	ВремяВыполненияВМиллисекундах = ОкончаниеТочноеВремяМиллисекунды - НачалоТочноеВремяМиллисекунды;
	ВремяРаботыСекунд = цел(ВремяВыполненияВМиллисекундах/1000);
	ФорматВремени = "ДЛФ=В";
	
	ВремяВыполнения = "Окончание замера времени. Время работы (секунд:миллисекунд): "+ФОРМАТ(ВремяРаботыСекунд,"ДЛФ=T")+":"+Формат(ВремяВыполненияВМиллисекундах - ВремяРаботыСекунд*1000, "ЧЦ=3; ЧН=000; ЧВН=");
	Сообщить(ВремяВыполнения, СтатусСообщения.Важное);	
	
	Возврат МассивЧисел; // Из строки в начале функции, получается массив: 234224, 555 и 1
КонецФункции

Скачать файлы

Наименование Файл Версия Размер
Строка в число 2
.epf 9,00Kb
21.01.16
2
.epf 9,00Kb Скачать

См. также

PowerTools от 1 000
Подписаться Добавить вознаграждение

Комментарии

1. Петр Лунегов (pvlunegov) 21.01.16 16:10
Прошу прощения за опечатки в тексте. Позже исправлю
2. Андрей Крутских (K_A_O) 25.01.16 10:06
Вроде бы сейчас стандартный способ через ОписаниеТипов:

ОписаниеТипаЧисло = новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Длина, Точность, ДопустимыйЗнак[Знак]));
возврат ОписаниеТипаЧисло.ПривестиЗначение( Строка ) ;

3. Петр Лунегов (pvlunegov) 25.01.16 14:32
(2) K_A_O, это вопрос или утверждение? или совет?
поясняйте как то, непонятно что вы имеете ввиду
4. Андрей Крутских (K_A_O) 25.01.16 15:02
(3) Даже не знаю, что это. Просто выбрано для тестирования 2 способа. А типовой на скорость не проверен. Почему он обделен, не должен быть медленным.

5. Петр Лунегов (pvlunegov) 25.01.16 16:14
(4) K_A_O,
Вы пробовали ваш метод на строках вида
"укпорто348567ыквпрв
3847ошпи34895ои"?

Знаете возвращает метод приведения типов от такой строки?
Попробуйте.
Ваш метод подходит для одного числа в строке.
А если их несколько и заранее неизвестно количество чисел в строке?
6. Петр Лунегов (pvlunegov) 25.01.16 16:17
Вы в курсе, что преобразовать число в строку - можно. См. пример http://v8.1c.ru/predpriyatie/typical_problems_Types.htm

А ОБРАТНАЯ ОПЕРАЦИЯ - СТРОКА В ЧИСЛО - НЕЛЬЗЯ!
Будет ошибка преобразования типов.

Это логично. Как вам интерпретатор преобразует "врп346вар" в число?
7. Андрей Крутских (K_A_O) 26.01.16 13:26
8. Владимир Лагутин (Lukich66) 27.01.16 20:45
Для полного "самоуспокоения" предусмотреть и вариант формирования дробных чисел в массиве
9. Дмитрий Егоров (Diego_Iv) 28.01.16 12:45
Регулярные выражения - вещь!!!
Допиливал с их использованием обработку "Клиент-банк".

У нас в день 100-200 входящих платежек (поступление на расчетный счет).
У контрагента может быть от 1 до 10 действующих договоров. Все они приучены, что в назначении платежа обязательно указывают тот номер договора, по которому перечисляются деньги.

Теперь Клиент-банк распознает этот номер и правильно подставляет нужный договор в документ (ранее подставлялся договор, назначенный основным и приходилось вручную исправлять его, глядя на то, что написано в назначении платежа).
Теперь все делается "само", бухи счастливы.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа