我打电话给某个方法当我单独使用它时需要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;
}
运行验证请求方法的其他上下文
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 ");
}
}
}
答案 0 :(得分:5)
当你预热代码时,它会根据它的使用方式变得更快。
第一次运行它时,它非常慢,它必须加载类并初始化它们。
当您重复运行代码时,不仅预热代码并且触发编译它的部分在缓存中也会更温暖,例如L1访问速度比主存储器访问速度快100倍。
如果您运行代码10K或20K次,所有代码都将在缓存中编译和加热,并且分支预测工作得很好。
即便如此,如果您上下文切换并执行其他操作,您会看到再次减速,因为您的缓存不是那么温暖。你可以看到减速度高达2-5倍。
BTW还存在其他因素,例如资源瓶颈,CPU为降低功率而节省电力并以较低频率运行。答案 1 :(得分:1)
查看您的代码,我发现只有在encryptedTicket.length%16==0
时才会执行困难的部分。这对我来说很奇怪。你真的想在这说什么?我怀疑2的幂的模数是否有任何真正的性能影响,但如果你不小心,你可以不一致地输入代码的计算密集型部分用于不同的测试运行。或者,当使用真实世界的数据时,你可能会得到一个非现实世界的结果导致悲伤。
此外,在进行性能测试时,请确保从任何内部方法评论System.output()
。海森堡正在观望 - 你衡量的越多,你改变结果就越多。
如果95000 nSec是一个普通输出,而你平均需要11500ns,那么你就可以完成工作了。加密例程可能已经非常严格,无论如何都无法更改。所以你必须改变你调用它的频率或validateRequest(...)
中其他内容的负载。例如,如果ClientTicketManager.getArpCash().put(...)
实际上正在进行实际I / O,则可以通过在自己的线程中运行多个validateRequest(...)
来获得提升。然后,当一个线程忙时,另一个线程可以为新请求提供服务。