方法的表现

时间:2013-06-16 14:21:08

标签: java

我打电话给某个方法当我单独使用它时需要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 ");
        }
    }

}

2 个答案:

答案 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(...)来获得提升。然后,当一个线程忙时,另一个线程可以为新请求提供服务。