Comment serrer nanosecondes sur une boucle de java

Les meilleures astuces sont les trucs les plus simples. Alors continuez à lire pour être présenté à un truc simple qui a été autour depuis des siècles - un truc qui peut couper la moitié de la durée de fonctionnement d'une boucle de programme Java.

Imaginez la recherche à travers une longue liste de noms. Annonce 1 a un peu de code pour illustrer l'idée.

Liste 1: Recherche d'un nom

import-import java.io.IOException java.io.File-import java.util.Scanner publiques classe Main {static Scanner fichier disque-static int MAX_SIZE = String nom 100-statique [] = new String [MAX_SIZE] vide -Santé statique main (String [] args) throws IOException {fichier disque = new Scanner (new File ("names.txt")) - int NumberOfNames = fillTheArray () - SearchFor ("Burd", NumberOfNames) -} static int fillTheArray () {int i = 0-tout (diskFile.hasNext () je lt; MAX_SIZE) {nom [i ++] = diskFile.next () -} return i-} static SearchFor vide (String whatToSearchFor, int NumberOfNames) {int i = 0-alors que je lt; NumberOfNames   !Nom [i] .equals (whatToSearchFor)) { i ++ -}si je lt; NumberOfNames) { System.out.println ("Trouvé à la position" + i) -} Else { System.out.println ("Not found") -}}}

Le code du listing 1 présente un tableau de noms. Le nombre d'entrées dans le tableau est NumberOfNames. Le code en gras au bas de la liste vérifie à plusieurs reprises pour une entrée contenant les mêmes caractères que whatToSearchFor (dans cet exemple, le nom "Burd").

La boucle vérifie également à plusieurs reprises pour faire en sorte que je est inférieur à NumberOfNames. Sans cette vérification, la course de votre programme peut venir écraser avec un NullPointerException ou un ArrayIndexOutOfBoundsException. Voici pourquoi:

  • Imaginez que le names.txt fichier contient trois noms: "Bouclé", "Larry", et "Moe". alors Nom [0] est "Bouclé", Nom [1] est "Larry", et Nom [2] est "Moe". Il n'y a pas Nom [3] valeur. (Être plus précis, Nom [3] est nul.)

    La valeur de NumberOfNames 3. Sans est le je lt; NumberOfNames vérifier, le programme vérifie !Nom [3] .equals (whatToSearchFor). Mais Nom [3] est nul si la course du programme explose avec le NullPointerException.

  • Imaginez que le fichier names.txt contient 100 noms, et que MAX_SIZE est de 100. Puis chaque entrée dans le nom tableau contient une chaîne honnête-à-bonté. Les entrées dans le nom tableau sont Nom [0], Nom [1], et ainsi de suite, tout le chemin jusqu'à nom [99]. Il n'y a pas Nom [100] entrée.




    Sans le je lt; NumberOfNames vérifier, le programme vérifie !Nom [100] .equals (whatToSearchFor). Mais Nom [100] ne pas exister, donc la course du programme mord la poussière avec le ArrayIndexOutOfBoundsException.

D'une façon ou une autre, vous avez apparemment pour vérifier deux choses à chaque fois dans la boucle: Vous devez vérifier si je lt; NumberOfNames puis vérifier si !Nom [i] .equals (whatToSearchFor).

Alors la grande question est, Pouvez-vous faire mieux? Pouvez-vous vérifier une seule condition au lieu de deux? Et la réponse (comme si vous ne l'avez pas déjà deviné) est "Oui, vous le pouvez." Cette astuce particulière ne réduit pas le temps de fonctionnement du programme par bonds, mais il est un truc mignon quand même. Voici l'idée:

Jamais lu dans tant de noms que vous ne possédez pas au moins un réseau entrée vide. Puis, après la dernière entrée du tableau honnête à la bonté, ajouter une entrée de gamme plus savoir, le nom que vous souhaitez rechercher. Avec ce nom supplémentaire à la fin du tableau, vous ne disposez pas de garder le contrôle je lt; NumberOfNames. Maintenant, l'autre condition, !Nom [100] .equals (whatToSearchFor), doit devenir fausse avant vous manquez d'entrées de tableau.

Listing 2 contient du code pour illustrer cette idée. (Les différences entre Listing 2 et annonce 1 sont indiqués en caractères gras dans le listing 2.)

Liste 2: Un peu mieux fouille de routine

import-import java.io.IOException java.io.File-import java.util.Scanner publiques classe Main {static Scanner fichier disque-static int MAX_SIZE = String nom 100-statique [] = new String [MAX_SIZE] vide -Santé statique main (String [] args) throws IOException {fichier disque = new Scanner (new File ("names.txt")) - int NumberOfNames = fillTheArray () - SearchFor ("Burd", NumberOfNames) -} static int fillTheArray () {int i = 0-tout (diskFile.hasNext () je lt; MAX_SIZE - 1) {Nom [i ++] = diskFile.next () -} return} i- SearchFor static void (String whatToSearchFor, int NumberOfNames) {Nom [] = NumberOfNames whatToSearchFor-int i = 0-tout (!Nom [i] .equals (whatToSearchFor)) {I ++ -} if (i lt; NumberOfNames) {System.out.println ("Trouvé à la position" + i) -} else {System.out.println ("Not found") -}}}

Dans le Listing 2, la valeur MAX_SIZE - 1 assure que le tableau a au moins une entrée vide. La déclaration

Nom [NumberOfNames] = whatToSearchFor-

place le nom que vous avez l'intention de chercher après la dernière entrée du tableau honnête à la bonté. Et la condition !Nom [i] .equals (whatToSearchFor) vérifie les entrées de tableau jusqu'à ce qu'il trouve un nom à partir de la names.txt fichier ou le nom que vous avez placé artificiellement après la dernière entrée.

Voilà donc l'affaire. En ajoutant une entrée supplémentaire à la fin de la liste, vous allez de vérifier deux conditions à plusieurs reprises

alors que je lt; NumberOfNames ! nom [i] .equals (whatToSearchFor))

de vérifier une seule condition à plusieurs reprises:

while (! nom [i] .equals (whatToSearchFor))

Voici un fait intéressant à propos de l'affaire décrit dans cet article: Vous ne devez pas un programme Java pour utiliser cette astuce. En fait, on n'a même pas besoin d'un ordinateur! L'astuce applique à toutes sortes de situations qui impliquent la recherche - la recherche effectuée par les ordinateurs, la recherche effectuée par des robots, et même des recherches effectuées par les êtres humains.

Imaginez avoir une longue lignée de boîtes, et de raconter votre assistant pour trouver un pamplemousse dans l'une des cent premières boîtes. (Demain, quelqu'un d'autre va commencer à regarder à partir de la boîte 101e en avant.) Vous pouvez avoir vos assistants comptent boîtes dans leur recherche, mais qui veut garder la trace de boîte chiffres dans leur recherche? Si vous savez déjà où la boîte est 101e, mettre un marqueur sur cette boîte et de dire à votre assistant de recherche à la marqueur. Mieux encore, mettre, un pamplemousse plastique faux dans la boîte 101e et simplement dire à votre assistant pour trouver un pamplemousse.

Le même genre de raisonnement fonctionne dans des situations moins artificiel. Une recette de lasagnes nécessite 50 minutes dans le four. Vous pourriez commencer à chauffer la lasagne à 17h53 et de regarder l'horloge toutes les minutes. Quand, enfin, vous avez compté hors 50 minutes, vous prenez la lasagne la sortie du four.

Mais compter minutes est ennuyeux. Alors que vous regardez en arrière à l'horloge, vous pourriez manquer une partie de votre spot TV préférée. Au lieu de faire tout ce comptage, mettre un marqueur à la fin du processus en réglant votre minuterie de cuisine pour aller hors en 50 minutes.

Tu vois? Il n'y a pas que Java. Il est le bon sens.


» » » » Comment serrer nanosecondes sur une boucle de java