1. 程式人生 > >效能提升5000倍,我都不敢信

效能提升5000倍,我都不敢信

之前組裡人寫了個解密工具,用cmd呼叫jar包裡的方法

@echo off
echo %time%
echo.
set key=8076yda4404ysh09
for /f  %%i in (str.txt) do java -jar encrypt.jar aescbc d %%i %key%
echo.
echo %time%
pause

echo %time%為後期加上為了統計時間的,可以看到的是依次讀取str.txt的內容,並解密,實測了一下,解密8k條資料需要花費50多分鐘,那時間會是耗在哪兒呢?如果要修改應該怎麼修改呢?

修改為直接在java中讀取檔案並一次性解密,程式碼如下:

public class DecryptMain
{
    static List<String> originalList = new ArrayList<String>(1024);
    
    static List<String> resultList = new ArrayList<String>(1024);
    
    /**
     * 讀取檔案儲存到list
     */
    static void readOriginalFile()
    {
        try
        {
            originalList = Files.readAllLines(Paths.get("str.txt"));
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
    
    /**
     *  解密後寫入list然後寫入檔案
     *
     * @param list 原始list
     * @param encryptKey  key
     */
    static void decrypt(List<String> list, String encryptKey)
    {
        list.forEach(str ->
        {
            try
            {
                resultList.add(AESCBCEncrypter.getInstance().decrypt(str, encryptKey));
            }
            catch (EncryptException e)
            {
                e.printStackTrace();
            }
        });
    }

    /**
     * 將結果List寫入檔案
     */
    private static void writeResult()
    {
        try
        {
            Files.write(Paths.get("result.txt"), resultList, StandardOpenOption.CREATE);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args)
    {
        String key = "8076yda4404ysh09";
        if (args.length > 0)
        {
            key = args[0];
        }
        
        readOriginalFile();
        decrypt(originalList, key);
        writeResult();
    }    
}

工程pom.xml如下

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>decrypt</groupId>
  <artifactId>decrypt</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
        <dependency>
            <groupId>music-encrypt</groupId>
            <artifactId>music-encrypt</artifactId>
            <version>1.0.0</version>
        </dependency>
  </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>${exec.mainClass}</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archiverConfig>
                        <encoding>utf-8</encoding>
                    </archiverConfig>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <properties>
    	<exec.mainClass>decrypt.DecryptMain</exec.mainClass>
    </properties>
</project>

其中依賴的包通過如下命令安裝到本地

mvn install:install-file    -D file=src\main\resources\encrypt.jar    -D groupId=music-encrypt    -D artifactId=music-encrypt    -D version=1.0.0    -D packaging=jar    -D generatePom=true

最後

mvn assembly:assembly 

生成可執行jar包,修改bat檔案為:

@echo off
echo %time%
echo.
set key=8076yda4404ysh09
java -jar decrypt.jar %key%
echo.
echo %time%
pause

實測600多毫秒即可完成,實際測試了一下,發現解密一條資料的耗時在200-300ms,java -jar命令一次耗時在100多ms,所以之前每一次單獨解密8k條資料的耗時在8000*(100+300)=53分鐘;載入後一起解密8k條資料的耗時在500ms,加上java -jar一次100ms,所以修改後可以600ms搞定,相當於提升了5000多倍,吹牛都不敢這樣吹的一個提升效率比,說明選對方式很重要啊。小工具內部使用,一來,之前沒有解密這麼資料的需求;二來,之前的jar包是別的部門給的jar包,沒有原始碼,做工具的同事也沒想到mvn install到本地,在打包進咱自己包,同時修改可執行jar包的main類吧。