Tout d'abord, je viens de me créer une expression régulière qui correspondra à tous les chemins de bibliothèque externes uniques dans une liste de tous les fichiers d'en-tête d'un projet. J'ai posé une question concernant la création de cette expression rationnelle il y a une semaine.
J'ai commencé à me mêler pour voir comment il se comporterait lorsqu'il était asynchrone et transformé en travailleur Web. Pour plus de commodité et de fiabilité, j'ai créé ce fichier universel qui s'exécute dans les trois modes:
/** Will call result() callback with every match it founds. Asynchronous unless called
* with interval = -1.
* Javadoc style comment for Arnold Rimmer and other Java programmers:
*
* @param regex regular expression to match in string
* @param string guess what
* @param result callback function that accepts one parameter, string match
* @param done callback on finish, has no parameters
* @param interval delay (not actual interval) between finding matches. If -1,
* function will be blocking
* @property working false if loop isn't running, otherwise contains timeout ID
* for use with clearTimeout
* @property done copy of done parameter
* @throws heavy boulders
**/
function processRegex(regex, string, result, done, interval) {
var m;
//Please tell me interpreter optimizes this
interval = typeof interval!='number'?1:interval;
//And this
processRegex.done = done;
while ((m = regex.exec(string))) {
Array.prototype.splice.call(m,0,1);
var path = m.join("");
//It's good to keep in mind that result() slows down the process
result(path);
if (interval>=0) {
processRegex.working = setTimeout(processRegex,
interval, regex, string,
result, done, interval);
// Comment these out for maximum speed
processRegex.progress = regex.lastIndex/string.length;
console.log("Progress: "+Math.round(processRegex.progress*100)+"%");
return;
}
}
processRegex.working = false;
processRegex.done = null;
if (typeof done=="function")
done();
}
processRegex.working = false;
J'ai créé un fichier de test, plutôt que de le coller ici, je l'ai téléchargé sur un hébergement Web très fiable: Démo - Données de test .
Ce que je trouve très surprenant, c'est qu'il y a une telle différence significative entre l'exécution du web worker et du navigateur de RegExp. Les résultats que j'ai obtenus:
- Mozilla Firefox
[WORKER]: Time elapsed:16.860s
[WORKER-SYNC]: Time elapsed:16.739s
[TIMEOUT]: Time elapsed:5.186s
[LOOP]: Time elapsed:5.028s
Vous pouvez également voir qu'avec mon expression régulière particulière, la différence entre une boucle synchrone et asynchrone est insignifiante. J'ai essayé d'utiliser une liste de correspondance au lieu d'une expression anticipée et les résultats ont beaucoup changé. Voici les modifications apportées à l'ancienne fonction:
function processRegexUnique(regex, string, result, done, interval) {
var matchList = arguments[5]||[];
... same as before ...
while ((m = regex.exec(string))) {
... same as before ...
if (matchList.indexOf(path)==-1) {
result(path);
matchList.push(path);
}
if (interval>=0) {
processRegex.working = setTimeout(processRegex, interval,
regex, string, result,
done, interval, matchList);
... same as before ...
}
}
... same as before ...
}
Et les résultats:
- Mozilla Firefox
[WORKER]: Time elapsed:0.062s
[WORKER-SYNC]: Time elapsed:0.023s
[TIMEOUT]: Time elapsed:12.250s
(Note à moi-même: ça devient de plus en plus bizarre à chaque minute)[LOOP]: Time elapsed:0.006s
Quelqu'un peut-il expliquer une telle différence de vitesse?