方法的表现

我打电话给某个方法当我单独使用它时需要11523纳秒的平均值(10000次调用)但是当我从另一个类的上下文中调用它时需要大约95721

方法体是

public static byte [] validateRequest(KARPPacket karpPacket) { try { long before,time; before =System.nanoTime(); byte [] encryptedTicket=karpPacket.getTicket(); byte[] decryptedTicket=null; if(encryptedTicket==null) return null; if(encryptedTicket.length%16==0) { decryptedTicket = Encryptor.decrypt(encryptedTicket, ClientWindow.getSecretKey()); time=System.nanoTime()-before; System.out.println(time); if(karpPacket.getSenderProtocolAddressAsString().equals(getSrcAddressFromTicket(decryptedTicket))) { ClientTicketManager.getArpCash().put(karpPacket.getSenderProtocolAddressAsString(), karpPacket.getSenderHardwareAddressFormatted()); return decryptedTicket; } return decryptedTicket; } return null; } catch (Exception e) { e.printStackTrace(); return null; } 

为什么这样以及如何改善其性能。 我希望这个代码足够了

这是encryptor.decrypt方法

 public static byte[] decrypt(byte [] encryptedByteArray,String keyString)throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { SecretKey key=loadKey(keyString); byte[] clearByteArray; Cipher dCipher=Cipher.getInstance("AES"); dCipher.init(Cipher.DECRYPT_MODE,key ); clearByteArray=dCipher.doFinal(encryptedByteArray); return clearByteArray; 

}

和加载密钥

 public static SecretKey loadKey(String keyString) { byte[] encoded = keyString.getBytes(); SecretKey key = new SecretKeySpec(encoded, "AES"); return key; } 

运行validation请求方法的其他上下文

 package karp.client; import java.awt.Color; import java.net.Inet4Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.sql.Timestamp; import java.util.Date; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.swing.JOptionPane; import javax.swing.text.Style; import javax.swing.text.StyleConstants; import javax.swing.text.StyledDocument; import karp.client.presentation.ClientWindow; import karp.client.util.Constants; import karp.generalutil.common.Encryptor; import karp.generalutil.destination.TicketDestination; import karp.packet.KARPPacket; public class KARPMessageHandlerP { String localIpAddress=null; ClientTicketManager clientTicketManager; KARPSender karpRequestSender=new KARPSender(); byte [] srcMac; NetworkInterface network; public KARPMessageHandlerP(KARPPacket karpPacket) { try { long before,time; localIpAddress=KARPReciever.localIpAddress; clientTicketManager=KARPReciever.clientTicketManager; srcMac = KARPReciever.srcMac; // if(karpPacket.getOperation()==KARPPacket.ARP_REPLY) { if(karpPacket.getSenderProtocolAddressAsString().equals(localIpAddress))//request sent by client { // if the reply was sent by the client no action must be taken. } else { if(karpPacket.getTargetProtocolAddressAsString().equals(localIpAddress)) { byte [] ticket=karpPacket.getTicket(); if(ticket==null) { //delete the new entry from cash and refresh the cash deleteEntry(karpPacket.getSenderProtocolAddressAsString()); } else { if(validateReply(karpPacket) ) { } else { deleteEntry(karpPacket.getSenderProtocolAddressAsString()); //delete entry and refresh cash } } } } } else if(karpPacket.getOperation()==KARPPacket.ARP_REQUEST) { if(karpPacket.getSenderProtocolAddressAsString().equals(localIpAddress))//request sent by client { //1 if(karpPacket.getTicket()!=null) { //custom request no need to add; } //2 else //new request need to add ticket { String destinationId=(karpPacket.getTargetProtocolAddressAsString()); // if the map contain ticket to destination add the ticket directly //2-1 KARPPacket customKarpPacket; byte [] ticketDestinationByte=null; if(ClientTicketManager.getDestinationTicketMap().containsKey(destinationId)) { ticketDestinationByte=ClientTicketManager.getDestinationTicketMap().get(destinationId); } //2-2 send ticket request else { ticketDestinationByte=clientTicketManager.getDestinationTicket(destinationId); } if(ticketDestinationByte!=null) { customKarpPacket= karpRequestSender.createKARPPacket(karpPacket.getDstAddress(), karpPacket.getSrcAddress(), InetAddress.getLocalHost().getAddress(), karpPacket.getTargetProtoAddr(), karpPacket.getTargetHardAddr(), ticketDestinationByte, KARPPacket.ARP_REQUEST); karpRequestSender.sendKARPPacket(customKarpPacket); } } } else { if(karpPacket.getTargetProtocolAddressAsString().equals(localIpAddress))//check to see if the request is for the client { byte [] ticketRequest=validateRequest(karpPacket); if(ticketRequest!=null) { //reply to the request; String sessionKey=getSessionKeyFromTicket(ticketRequest); TicketDestination ticketDestination=new TicketDestination(); ticketDestination.setDestinationId(karpPacket.getSenderProtocolAddressAsString()); ticketDestination.setSourceId(karpPacket.getTargetProtocolAddressAsString()); ticketDestination.setSourceDestinationKey(sessionKey); byte [] ticketDestinationByte=ticketDestination.getAsByte(); byte [] encryptedTicketDestination=Encryptor.encrypt(ticketDestinationByte, sessionKey); ///need to review target hardware address KARPPacket karpPacketReply=karpRequestSender.createKARPPacket(karpPacket.getSrcAddress(), srcMac, InetAddress.getLocalHost().getAddress(), karpPacket.getSenderProtoAddr(),karpPacket.getSrcAddress(), encryptedTicketDestination, KARPPacket.ARP_REPLY); karpRequestSender.sendKARPPacket(karpPacketReply); } else //delete ticket invalid request { deleteEntry(karpPacket.getSenderProtocolAddressAsString()); } } } } } catch(Exception e) { e.printStackTrace(); } //System.out.println(timeConsumed); } public static byte [] validateRequest(KARPPacket karpPacket) { try { long before,time; before =System.nanoTime(); byte [] encryptedTicket=karpPacket.getTicket(); byte[] decryptedTicket=null; if(encryptedTicket==null) return null; if(encryptedTicket.length%16==0) { decryptedTicket = Encryptor.decrypt(encryptedTicket, ClientWindow.getSecretKey()); time=System.nanoTime()-before; System.out.println(time); if(karpPacket.getSenderProtocolAddressAsString().equals(getSrcAddressFromTicket(decryptedTicket))) { ClientTicketManager.getArpCash().put(karpPacket.getSenderProtocolAddressAsString(), karpPacket.getSenderHardwareAddressFormatted()); return decryptedTicket; } return decryptedTicket; } return null; } catch (Exception e) { e.printStackTrace(); return null; } } public boolean validateReply(KARPPacket karpPacket) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { // KARPReciever.stop=true; // for(int i=0;i<10000;i++) // { String sessionKey; byte[] encryptedTicket=karpPacket.getTicket(); if(ClientTicketManager.getDestinationKeyMap().containsKey(karpPacket.getSenderProtocolAddressAsString())) { sessionKey=ClientTicketManager.getDestinationKeyMap().get(karpPacket.getSenderProtocolAddressAsString()); byte[] decryptedTicket=Encryptor.decrypt(encryptedTicket, sessionKey); if(karpPacket.getSenderProtocolAddressAsString().equals(getSrcAddressFromTicket(decryptedTicket))) { ClientTicketManager.getArpCash().put(karpPacket.getSenderProtocolAddressAsString(), karpPacket.getSenderHardwareAddressFormatted()); // after=System.nanoTime(); // timeConsumed=(after-before); // System.out.print("kl"+timeConsumed); return true; } } //} return false; } public void deleteEntry(String entryIpAddress) { try { if(!ClientTicketManager.getAuthenticatedUser().contains(entryIpAddress)) { if(ClientTicketManager.getArpCash().containsKey(entryIpAddress)) { String updateCommand="arp -s "+entryIpAddress+" "+clientTicketManager.getArpCash().get(entryIpAddress); //printCash(); Runtime.getRuntime().exec(updateCommand); } else { String deleteCommand ="arp -d "+entryIpAddress; Runtime.getRuntime().exec(deleteCommand); } } } catch(Exception e) { } } public static String getSrcAddressFromTicket(byte [] ticket) { byte [] srcByte=new byte[4]; System.arraycopy(ticket, 16, srcByte, 0, 4); String srcString=TicketDestination.getIpAddressAsString(srcByte); return srcString; } public String getSessionKeyFromTicket(byte [] ticket) { byte [] sessionKeyByte=new byte[16]; System.arraycopy(ticket, 0, sessionKeyByte,0, 16); return new String(sessionKeyByte); } public void printCash() { for(Object entry:ClientTicketManager.getArpCash().entrySet().toArray()) { System.out.println(entry+" "+clientTicketManager.getArpCash().get(entry)+" entry in cash "); } } } 

当你预热代码时,根据它的使用方式,它会变得更快。

第一次运行它时,它非常慢,它必须加载类并初始化它们。

当您重复运行代码时,不仅预热代码并且触发编译它的部分也将在缓存中变得更暖,例如L1访问可以比主存储器访问快100倍。

如果您运行代码10K或20K次,则所有代码都将在缓存中编译和加热,并且分支预测工作得很好。

即便如此,如果您上下文切换并执行其他操作,您会看到再次减速,因为您的缓存不是那么温暖。 你可以看到减速高达2-5倍。

BTW还有其他因素,例如资源瓶颈,CPU为降低功率而节省电力并以较低频率运行。

看看你的代码,我发现只有在encryptedTicket.length%16==0时才能完成难点。 这对我来说很奇怪。 你真的想在这说什么? 我怀疑2的幂的模数是否有任何真正的性能影响,但如果你不小心,你可以在不同的测试运行中不一致地输入代码的计算密集型部分。 或者,当使用真实世界的数据时,您可能会得到一个非现实世界的结果导致悲伤。

此外,在进行性能测试时,请确保从任何内部方法注释System.output() 。 海森堡正在观望 – 你测量的越多,你改变的结果就越多。

如果95000 nSec是一个常见的输出,而你平均需要11500ns,那么你就可以完成工作了。 加密例程可能已经很紧,你无论如何都无法改变它。 因此,您必须更改在validateRequest(...)调用它的频率或其他内容的负载。 例如,如果ClientTicketManager.getArpCash().put(...)实际上是在进行真正的I / O,那么可以通过在自己的线程中运行几个validateRequest(...)来获得提升。 然后,当一个线程忙时,另一个线程可以为新请求提供服务。