Поведение метода странного регулярного выражения в JS - PullRequest
1 голос
/ 19 февраля 2020

Столкнулся с такой проблемой. Когда вы запускаете exe c или метод match, первый вызов метода всегда медленнее, чем второй. Последующие вызовы - будут выполняться еще быстрее.

0:       0.013281777024269104
1:       0.004966034680604935
2:       0.004561618596315384
3:       0.004366877138614654
4:       0.003996829882264137
5:       0.0037765540182590485
6:       0.00369636969268322
7:       0.003592779144644737
8:       0.0036278150379657746
9:       0.003481139928102493
10:      0.0035037004351615906
11:      0.004023797005414963
12:      0.003495175927877426
13:      0.0035397831946611404
14:      0.0034795581251382828
15:      0.0033910408914089203
16:      0.0033861002922058107
17:      0.0033773958384990693
18:      0.003347825139760971
19:      0.0034435260742902755

Насколько я понимаю, движок V8 как-то кеширует данные. И при следующем запуске метода - это помогает ему выполнить его быстрее. Только не могу понять механизм такого кеширования.

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

Я написал небольшой пример ниже:

  • внутри для l oop, мы получаем случайную строку с фиксированной длиной;
  • в случайной строке, в случайном месте помещается строка для поиска;
  • итерации и циклы выполняются указанное количество раз;
  • среднее значение времени работы рассчитывается: 0,1,2 ... расчет.

// const { performance } = require('perf_hooks'); // comment out if this will run in the browser

const wordLength = 1000; // random string length
const searchString = `aBc123%!@#$%^&*()_-+=[]{}<>,./|*`; // used for regular expression and for substituting in a random string in a random place
let iterationCount = 100; // iterator start counter
const calculationsCount = 20; // number of calculations in one iteration
const timeOut = 30; // delay in ms between the iterator function call
const result = {};


const randomString = (length) => [...Array(length)].map(_ => (Math.random() * 36 | 0).toString(36)).join``;
const randomNumber = (max) => Math.floor(Math.random() * max);
const regEscaping = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');


const reg = new RegExp(regEscaping(searchString), "g");


const prepareResult = () => {
	for (let i = 0; i < calculationsCount; i++) {
		result[i] = [];
	}
}
prepareResult();


const iterator = () => {
	let tmp = result;

	for (let i = 0; i < calculationsCount; i++) {
		let text = randomString(wordLength);
		let position = randomNumber(wordLength);
		text = text.substr(0, position) + searchString + text.substr(position); // since the global key is used, random placement will not affect the result

		let start = performance.now();
		let result = text.match(reg);
		let end = performance.now();
		tmp[i].push(end - start);
	}

	iterationCount--;
	if (iterationCount) {
		setTimeout(iterator, timeOut);

	} else {
		for (let i = 0; i < calculationsCount; i++) {
			console.log(`${i}: \t ${tmp[i].reduce((a, b) => (a + b)) / tmp[i].length}`);
		}
	}
}
iterator();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...