6
votes

Est-ce que "startswith" plus rapide que "indexof"?

Je suis un code d'écriture en Java où je succursale sur la base d'une chaîne Démarre avec certains caractères tout en bouclant via un DataSet et mon Dataset > devrait être grand.

Je me demandais si startswith est plus rapide que indexof . J'ai expérimenté avec 2000 archives mais n'a trouvé aucune différence.


1 commentaires

J'ai fait une comparaison détaillée et l'a testée avec le nœud JS V10.10 et V11.15. J'ai trouvé que l'index est beaucoup plus rapide. Vous pouvez vérifier le résultat ici


8 Réponses :


3
votes

Probablement, si cela ne correspond pas, il peut arrêter de regarder alors que l'index doit rechercher des occurrences plus tard dans la chaîne.


0 commentaires

6
votes

Même sans regarder dans les sources, il devrait être clair que StartSwith est plus rapide au moins pour les grandes chaînes et les courts-courts:

Le temps d'exécution de A.StartSwith (B) est lié la longueur de b. Après au plus, les premiers caractères B sont cochés, la recherche est terminée.

L'heure d'exécution de A.Indexof (B) est plus grande (selon le Algorithme actuel ). Chaque algorithme a au moins une durée de fonctionnement en fonction de la longueur d'un. À peu près, vous pouvez dire que vous devez regarder chaque personnage une fois pour vérifier si le motif commence à cette position.

Cependant, comme toujours, cela dépend du cas d'utilisation réel si vous voyez vraiment une différence dans la pratique. Mesurer la différence dans la vie réelle n'est jamais mauvaise.


0 commentaires

8
votes

En général, la règle d'or de la micro-optimisation s'applique ici:

"Mesurer, ne devinez pas".

Comme pour toutes les optimisations de ce type, la différence entre les deux appels ne comptera pas presque certainement que si vous vérifiez des millions de cordes qui sont chacune des dizaines de milliers de caractères.

Exécutez un profileur sur votre code et optimisez uniquement cet appel lorsque vous pouvez mesurer que cela vous ralentit. Jusque-là, allez avec les options les plus lisibles (startswith, dans ce cas). Une fois que vous savez que ce bloc vous ralentit, essayez les deux et utilisez ce qui est plus rapide. Rincer. Répéter; -)

académiquement, je suppose que STARTSwewith sera probablement mis en œuvre à l'aide de l'indexof. Vérifiez le code source et voyez-vous si vous êtes intéressé. (s'avère que StartSwith n'appelle pas Indexof)


3 commentaires

Je suis vraiment vraiment espérons que StartSwith n'est pas implémenté avec Indexof. Considérez "une très longue chaîne qui ne commence pas avec X". Startswith ("X") - une implémentation efficace doit revenir après avoir vérifié le premier caractère, alors que l'utilisation de l'index de l'index doit parcourir la chaîne entière.


J'ai vérifié et StartSwith n'appelle pas Indexof. Crise atteinte.


Je suis surtout d'accord mais j'ai vu plusieurs développeurs qui utilisent indexof () == 0 pour savoir si une chaîne commence par "GET" (ou quelque chose). Probablement parce qu'ils ne l'ont jamais pensé et il est facile d'utiliser le même ancien marteau, peu importe ce que vous conduisez, ils les ont peut-être même comparés une fois (sur une petite chaîne) et ont compris qu'ils étaient plus ou moins Indenticulal, ne comprenant pas pourquoi la différence est énorme quand elles sont transmises à 10k bloc de données. La mesure est un bon début, mais il est encore plus important de comprendre pourquoi vous voyez les chiffres que vous obtenez de mesurer.



10
votes

startswith doit seulement vérifier la présence au début de la chaîne - il fait moins de travail, il devrait donc être plus rapide.

Je suppose que vos enregistrements de 2000 sont terminés dans quelques millisecondes (si cela). Chaque fois que vous souhaitez comparer une approche contre une autre, essayez de le faire pour suffisamment de temps que les différences de synchronisation seront importantes. Je trouve que 10-30 secondes sont suffisamment longues pour montrer des améliorations significatives, mais suffisamment courtes pour le rendre supportable d'exécuter plusieurs fois les tests. (Si c'était une enquête sérieuse, j'essaierais probablement plus de fois. La majeure partie de mon benchmarking est pour le plaisir.)

Assurez-vous également que vous avez des données variées - indexof et startswith devrait avoir à peu près le même temps d'exécution dans le cas où indexof retourne 0 . Donc, si tous vos enregistrements correspondent au modèle, vous ne testez pas vraiment correctement. (Je ne sais pas si tel était le cas dans vos tests bien sûr - c'est juste quelque chose à surveiller.)


0 commentaires

0
votes

Vous avez mentionné que l'ensemble de données devrait être important. Je parierai donc beaucoup de performance entrera dans l'accès à cet ensemble de données et la gérera en mémoire. Cela signifie que l'utilisation de l'un ou de l'autre ne changera pas la performance significative. Mais si cela est important pour vous, vous pouvez écrire votre propre méthode de démarrage qui pourrait être significative plus rapide que les méthodes de bibliothèque standard ou au moins vous savez exactement ce qui est fait.


0 commentaires

0
votes
public class Test
{
  public static void main(String args[]) {

    long value1 = System.currentTimeMillis();
    for(long i=0;i<100000000;i++)
    {
        "abcd".indexOf("a");
    }
    long value2 = System.currentTimeMillis();
    System.out.println(value2-value1);


    value1 = System.currentTimeMillis();
    for(long i=0;i<100000000;i++)
    {
        "abcd".startsWith("a");
    }
    value2 = System.currentTimeMillis();
    System.out.println(value2-value1);
  }
}
Tested it with this piece of code and perf for startsWith seems to be better, for obvious reason that it doesn't have to traverse through string. But in best case scenario both should perform close while in a worst case scenario startsWith will always perform better than indexOf

3 commentaires

Mais veuillez noter que bien que StartSwith puisse toujours être substitué à l'index de. Il n'est pas possible de remplacer l'index de StartSwith. Donc, d'une manière, la comparaison est entre oranges et pommes; Bien que pour un cas spécifique où vous pouvez vérifier si la chaîne commence par un jeu de caractères spécifique, vous pourrez peut-être utiliser les deux; Et pourtant, StartSwith est recommandé.


"L'index de et startwith doit avoir à peu près le même temps d'exécution dans le cas où Indexof retourne 0." Ce test a le problème que Jon était préoccupé - ce n'est peut-être pas une grande référence.


Indexof est plus rapide si la "entrée" a plus d'une lettre. StartSwith est plus rapide pour un seul caractère. Plus le mot, indexof performance. Essayez de faire une boucle avec 100 itérations et utilisez System.NanOTIME () à la place. Mais les résultats sont si minimums que vous ne devriez pas vous inquiéter lequel utiliser.



1
votes

startwith est plus clair que l'indexof == 0.

Avez-vous identifié le test comme un goulot d'étranglement de la performance pour lequel vous devez sacrifier la lisibilité?


0 commentaires

0
votes

Malheureux, StartSwith ne fonctionne pas comme censé! Il utilise "Indexof" derrière la scène (développeurs paresseux: D) de sorte que l'index est 10 fois plus rapide que la statistique mise en œuvre de STATSwith


1 commentaires

Désolé, je pensais que vous avez parlé de JavaScript: P