Je suis venu ici par hasard et je n'ai jamais eu de raison de répéter un caractère en javascript auparavant.
J'ai été impressionné par la façon de procéder d'artistoex et par les résultats de disfated. J'ai remarqué que la dernière concaténation de chaîne n'était pas nécessaire, comme Dennis l'a également souligné.
J'ai remarqué d'autres choses en jouant avec l'ensemble de l'échantillonnage.
Les résultats variaient considérablement, favorisant souvent la dernière course et des algorithmes similaires se disputaient souvent la position. L'une des choses que j'ai changées, c'est qu'au lieu d'utiliser le décompte généré par JSLitmus comme semence pour les appels, comme le décompte était généré différemment pour les diverses méthodes, j'ai mis un index. Cela a rendu la chose beaucoup plus fiable. J'ai ensuite cherché à m'assurer que des chaînes de taille variable étaient transmises aux fonctions. Cela a permis d'éviter certaines des variations que j'avais observées, où certains algorithmes étaient plus performants avec des caractères uniques ou des chaînes plus petites. Cependant, les trois méthodes les plus performantes ont toutes obtenu de bons résultats, quelle que soit la taille de la chaîne.
Ensemble de tests bifurqués
http://jsfiddle.net/schmide/fCqp3/134/
// repeated string
var string = '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789';
// count paremeter is changed on every test iteration, limit it's maximum value here
var maxCount = 200;
var n = 0;
$.each(tests, function (name) {
var fn = tests[name];
JSLitmus.test(++n + '. ' + name, function (count) {
var index = 0;
while (count--) {
fn.call(string.slice(0, index % string.length), index % maxCount);
index++;
}
});
if (fn.call('>', 10).length !== 10) $('body').prepend('<h1>Error in "' + name + '"</h1>');
});
JSLitmus.runAll();
J'ai ensuite inclus la solution de Dennis et j'ai décidé de voir si je pouvais trouver un moyen de gagner un peu plus.
Comme le javascript ne peut pas vraiment optimiser les choses, la meilleure façon d'améliorer les performances est d'éviter manuellement certaines choses. Si je retirais les 4 premiers résultats triviaux de la boucle, je pourrais éviter 2 à 4 chaînes de caractères et écrire la dernière chaîne directement dans le résultat.
// final: growing pattern + prototypejs check (count < 1)
'final avoid': function (count) {
if (!count) return '';
if (count == 1) return this.valueOf();
var pattern = this.valueOf();
if (count == 2) return pattern + pattern;
if (count == 3) return pattern + pattern + pattern;
var result;
if (count & 1) result = pattern;
else result = '';
count >>= 1;
do {
pattern += pattern;
if (count & 1) result += pattern;
count >>= 1;
} while (count > 1);
return result + pattern + pattern;
}
Cela s'est traduit par une amélioration de 1 à 2 % en moyenne par rapport à la solution de Dennis. Cependant, des exécutions différentes et des navigateurs différents montreraient une variance assez importante pour que ce code supplémentaire ne vaille probablement pas la peine d'être utilisé par rapport aux deux algorithmes précédents.
Un tableau
Edit : J'ai fait cela principalement sous chrome. Firefox et IE favorisent souvent Dennis de quelques %.
5 votes
Il y a plus de 10 ans, j'ai trouvé une solution bien connue à ce problème, que j'ai utilisée comme exemple dans un article sur l'optimisation du JavaScript quelques mois avant que vous ne posiez cette question : webreference.com/programmation/javascript/jkm3/3.html Apparemment, la plupart des gens ont oublié ce code, et je ne vois pas de solution aussi bonne que la mienne. Le meilleur algorithme semble avoir été repris de mon code ; sauf qu'en raison d'une mauvaise compréhension du fonctionnement de mon code, il effectue une étape supplémentaire de concaténation exponentielle qui est éliminée dans mon code original par une boucle spéciale.
0 votes
Veuillez essayer cette comparaison et envisager de remplacer la réponse acceptée par la solution de longue date à ce problème, publiée avant même que cette question ne soit posée. jsperf.com/repeating-strings
11 votes
Personne n'a levé la solution de Joseph. L'algorithme a 3700 ans. Le coût de cette étape supplémentaire est négligeable. En outre, le coût de l'étape supplémentaire est négligeable. cet article contient des erreurs et des idées fausses concernant la concaténation de chaînes de caractères en Javascript. Pour toute personne intéressée par la manière dont Javascript gère réellement les chaînes de caractères en interne, voir Corde .
4 votes
Personne ne semble avoir remarqué que String protoype repeat est défini et implémenté, au moins dans firefox.
3 votes
@kennebec : Oui, c'est une fonctionnalité d'EcmaScript 6 qui n'existait pas lorsque cette question a été posée. Elle est assez bien supportée maintenant.
3 votes
@rvighne - Je viens de vérifier kangax.github.io/compat-table/es6/#String.prototype.repeat Je ne considèrerais pas que le soutien apporté exclusivement par firefox et chrome soit "assez bien supporté"
1 votes
Comme l'indiquent le commentaire de Kennebec et la réponse d'André Laszlo, il s'agit d'ES6 :
'mystring'.repeat(xTimes)
1 votes
@brad Pourriez-vous changer la réponse acceptée en celui-ci , s'il vous plaît ?
0 votes
Bien sûr ! Je viens de le modifier.