Como espremer nanossegundos para fora de um loop java
Os melhores truques são os truques mais simples. Então continue lendo para ser apresentado a um truque simples que tem sido em torno de idades - um truque que pode cortar a metade o tempo de execução de um loop de programa Java.
Conteúdo
Imagine que pesquisar através de uma longa lista de nomes. Listagem 1 tem algum código para ilustrar a idéia.
Listagem 1: Como procurar um nome
importação java.io.File-import java.io.IOException-import classe java.util.Scanner-público principal {Scanner diskFile-static int MAX_SIZE = String name 100-estática [] = new String [MAX_SIZE] vazio -public estática estática main (String [] args) throws IOException {diskFile = new Scanner (new File ("names.txt")) - int = numberOfNames fillTheArray () - searchFor ("Burd", NumberOfNames) -} static int fillTheArray () {int i = 0-while (diskFile.hasNext () && Eu lt; MAX_SIZE) {name [i ++] = diskFile.next () -} retornar i-} static void searchFor (String whatToSearchFor, int numberOfNames) {int i = 0-enquanto eu lt; numberOfNames && !nomear [i] .equals (whatToSearchFor)) { i ++ -}se eu lt; numberOfNames) { System.out.println ("Encontrado na posição " + I) -} outro { System.out.println ("Não encontrado") -}}}
O código na Listagem 1 tem uma variedade de nomes. O número de entradas na matriz é numberOfNames. O código em negrito na parte inferior do perfil repetidamente verifica para uma entrada que contém os mesmos caracteres que whatToSearchFor (Neste exemplo, o nome “Burd”).
O circuito também verifica várias vezes para se certificar de que Eu é menos do que numberOfNames. Sem essa verificação, o funcionamento de seu programa pode desabar com um Null Pointer Exception ou um Índice de matriz fora dos limites de exceção. Aqui está o porquê:
Imagine que o names.txt arquivo contém três nomes: "Encaracolado", “Larry”, e “Moe”. Então Nome [0] é "Encaracolado", nomear [1] é “Larry”, e nomear [2] é “Moe”. Não há nomear [3] valor. (Para ser mais preciso, nomear [3] é nulo.)
O valor de numberOfNames é 3. Sem a Eu lt; numberOfNames verificar, o programa verifica !nomear [3] .equals (whatToSearchFor). Mas nomear [3] é nulo Então corra do programa explode com o Null Pointer Exception.
Imagine que o arquivo names.txt contém 100 nomes, e que MAX_SIZE é 100. Em seguida, cada entrada na nome matriz contém uma string honesto-a-bondade. As entradas no nome são matriz Nome [0], nomear [1], e assim por diante, todo o caminho até nome [99]. Não há nomear [100] entrada.
sem a Eu lt; numberOfNames verificar, o programa verifica !Nome [100] .equals (whatToSearchFor). Mas nomear [100] não existe, de modo prazo do programa morde a poeira com o Índice de matriz fora dos limites de exceção.
De uma forma ou de outra, você aparentemente tem que verificar duas coisas cada vez através do loop: Você tem que verificar se Eu lt; numberOfNames e, em seguida, verificar se !nomear [i] .equals (whatToSearchFor).
Então, a grande questão é, você pode fazer melhor? você pode verificar apenas uma condição, em vez de dois? E a resposta (como se você ainda não adivinhou) é “Sim, você pode.” Este truque particular não reduzir o tempo de execução do programa aos trancos e barrancos, mas é um truque bonito no entanto. Aqui está a idéia:
Nunca li em tantos nomes que você não tem pelo menos uma entrada array vazio. Em seguida, após a última entrada da matriz honesto-a-bondade, adicionar mais um entry- ou seja, o nome que pretende procurar. Com este nome extra no final do array, você não tem que manter a verificação Eu lt; numberOfNames. Agora, a outra condição, !Nome [100] .equals (whatToSearchFor),deve tornar-se falsa antes você ficar sem entradas de matriz.
Listagem 2 contém algum código para ilustrar essa idéia. (As diferenças entre Listagem 2 e Listagem 1 são marcados em negrito na Listagem 2.)
Listagem 2: Um pouco melhor Rotina de pesquisa
importação java.io.File-import java.io.IOException-import classe java.util.Scanner-público principal {Scanner diskFile-static int MAX_SIZE = String name 100-estática [] = new String [MAX_SIZE] vazio -public estática estática main (String [] args) throws IOException {diskFile = new Scanner (new File ("names.txt")) - int = numberOfNames fillTheArray () - searchFor ("Burd", NumberOfNames) -} static int fillTheArray () {int i = 0-while (diskFile.hasNext () && Eu lt; MAX_SIZE - 1) {Name [i ++] = diskFile.next () -} retornar i-} searchFor static void (String whatToSearchFor, int numberOfNames) {nomear [numberOfNames] = whatToSearchFor-int i = 0-tempo (!nomear [i] .equals (whatToSearchFor)) {I ++ -} if (i lt; numberOfNames) {System.out.println ("Encontrado na posição " + I) -} else {System.out.println ("Não encontrado") -}}}
Na Listagem 2, o valor MAX_SIZE - 1 assegura que a matriz tem, pelo menos, uma entrada em branco. A declaração
nomear [numberOfNames] = whatToSearchFor-
coloca o nome que você pretende procurar após a última entrada da matriz honesto-a-bondade. E a condição !nomear [i] .equals (whatToSearchFor) verifica entradas da matriz até encontrar um nome do names.txt arquivo, ou o nome que você colocou artificialmente após a última entrada.
Video: Java Tutorial For Beginners 14 - The for Statement in Java (for loops)
Então esse é o truque. Ao adicionar uma entrada extra no final da lista, você vai de verificação de duas condições repetidamente
enquanto eu lt; numberOfNames &&! Nome [i] .equals (whatToSearchFor))
de verificar apenas uma condição repetidamente:
while (! name [i] .equals (whatToSearchFor))
Aqui está um fato interessante sobre o truque descrito neste artigo: Você não precisa de um programa Java, a fim de usar esse truque. Na verdade, você não precisa sequer de um computador! O truque se aplica a todos os tipos de situações que envolvem a pesquisa - Encontrar feito por computadores, procurando feito por robôs, e até mesmo pesquisas feitas por seres humanos.
Imagine ter uma longa linha de caixas, e dizendo a seu assistente para encontrar uma toranja em qualquer um dos primeiros cem caixas. (Amanhã, alguém vai começar a olhar a partir da caixa 101 em diante.) Você pode ter seus assistentes contar caixas, em busca, mas quem quer manter o controle de contagem de caixa, em busca? Se você já sabe onde a caixa 101 é, colocar um marcador em que a caixa e dizer ao seu assistente de pesquisa até o marcador. Melhor ainda, colocar um grapefruit falso, plástico na caixa 101 e simplesmente dizer ao seu assistente para encontrar uma toranja.
O mesmo tipo de raciocínio funciona em situações menos artificial. Uma receita para lasanha requer 50 minutos no forno. Você poderia começar a aquecer a lasanha em 5:53 pm e olhar para o relógio a cada minuto ou assim. Quando finalmente você contou off 50 minutos, você toma a lasanha do forno.
Video: 5.6 Loop For, while, do while Java Tutorial Part 10 | Lecture
Mas contando minutos, é irritante. Enquanto você olhar de volta para o relógio, você pode perder parte do seu comercial de TV favorito. Em vez de fazer tudo isso contando, colocar um marcador no final do processo, definindo o seu temporizador de cozinha para sair em 50 minutos.
Entende? Não é apenas Java. É senso comum.