Java下AES加密單線程性速度280MB/s多線程450MB/s

測試目的

測試Java下的AES的加密速度。

測試環境

  • 機器1:

    • 硬件:i5 9600K + 16 GB DDR4 2666 + 512GB Intel 760P NVME
    • 軟件:Window 10 + Java 1.8.0_251
  • 機器2:

    • 硬件:i7 6500K + 8 GB DDR4 2666 + 1T機械硬盤
    • 軟件:Window 10 + Java 11.0.7

測試結果

根據以下測試結果,在第1次虛擬機熱身後,機器1的加密速度可以達到 280MB/s 左右,機器2可以達到130 MB/s - 170 MB/s。

機器1單線程測試結果

-------------- test 0 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 206.19 MB/s.
-------------- test 1 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 273.22 MB/s.
-------------- test 2 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 269.54 MB/s.
-------------- test 3 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 273.22 MB/s.
-------------- test 4 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 271.00 MB/s.
-------------- test 5 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 280.11 MB/s.
-------------- test 6 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 278.55 MB/s.
-------------- test 7 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 280.11 MB/s.
-------------- test 8 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 284.90 MB/s.
-------------- test 9 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 280.11 MB/s.

機器2單線程測試結果

-------------- test 0 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 76.92 MB/s.
-------------- test 1 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 97.09 MB/s.
-------------- test 2 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 141.04 MB/s.
-------------- test 3 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 175.75 MB/s.
-------------- test 4 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 169.20 MB/s.
-------------- test 5 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 133.69 MB/s.
-------------- test 6 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 136.61 MB/s.
-------------- test 7 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 133.87 MB/s.
-------------- test 8 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 138.12 MB/s.
-------------- test 9 --------------
Data.Length:   1.00 MB.
Running Times: 100.
Output.Length: 133.34 MB.
Encrypt Speed: 132.98 MB/s.

機器1多線程測試結果

# of Threads: 1	Length: 100.00 MB	Time: 628 ms	Speed: 159.24 MB/s.
# of Threads: 2	Length: 200.00 MB	Time: 628 ms	Speed: 318.47 MB/s.
# of Threads: 3	Length: 300.00 MB	Time: 743 ms	Speed: 403.77 MB/s.
# of Threads: 4	Length: 400.00 MB	Time: 898 ms	Speed: 445.43 MB/s.
# of Threads: 5	Length: 500.00 MB	Time: 1104 ms	Speed: 452.90 MB/s.
# of Threads: 6	Length: 600.00 MB	Time: 1324 ms	Speed: 453.17 MB/s.

測試代碼

單線程

package hao.tests;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class EncryptPerformanceTest {

	public static void main(String[] args) throws Exception {

		for(int test = 0; test < 10; test++) {
			System.out.printf("-------------- test %d --------------\n", test);
			encryptTest();
		}
	}
	
	static void encryptTest() throws Exception {
		// generate 1 MB data to be encrypted.
		StringBuilder sb = new StringBuilder();
		for(int i = 0; i < 1024 * 64; i++) 
			sb.append("Hello:0123456789");
		String data = sb.toString();
		
		int times = 100; // running times.
		int t = 0;       // total length of output
		long t1 = System.currentTimeMillis();
		for(int i = 0; i < times; i++) 
			t += encrypt(data, "0123456789ABCDEF").length();
		long t2 = System.currentTimeMillis();
		
		// print results.
		System.out.printf("Data.Length:   %.2f MB.\nRunning Times: %d.\nOutput.Length: %.2f MB.\nEncrypt Speed: %.2f MB/s.\n", 
				data.length()/1024.0/1024, times, t/1024.0/1024, 100.0 * 1000 / (t2-t1));
	} 
	
	public static String encrypt(String content, String key) throws Exception {
		SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec("1234567812345678".getBytes("utf-8")));
		byte[] bytes = cipher.doFinal(content.getBytes());
		String base64 = java.util.Base64.getEncoder().encodeToString(bytes);
		return base64; 
	}
}

多線程

package hao.tests;

import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class EncryptPerformanceTest implements Callable<Double> {

	public static CountDownLatch latch = new CountDownLatch(6);
	static int times = 10; // running times.
	static int totalLength = 0;
	static String key = "0123456789ABCDEF";

	public static void main(String[] args) throws Exception {
		for (int i = 0; i < 6; i++)
			test2(1 + i);
	}

	public static void test2(int count) throws InterruptedException {
		latch = new CountDownLatch(count);
		totalLength = 0;
		ExecutorService es = Executors.newCachedThreadPool();
		ArrayList<FutureTask<Double>> results = new ArrayList<FutureTask<Double>>();// [count];

		EncryptPerformanceTest[] epts = new EncryptPerformanceTest[count];
		for (int i = 0; i < epts.length; i++)
			epts[i] = new EncryptPerformanceTest();

		long t1 = System.currentTimeMillis();
		for (int i = 0; i < count; i++) {
			results.add((FutureTask<Double>) es.submit(new EncryptPerformanceTest()));
		}
		es.shutdown();
		latch.await();
		long t2 = System.currentTimeMillis();
		System.out.print("# of Threads: " + count + "\t");
		System.out.printf("Length: %.2f MB\tTime: %d ms\tSpeed: %.2f MB/s.\n", totalLength / 1048576.0, t2 - t1,
				totalLength / 1048576.0 / (t2 - t1) * 1000);
//		
//		for(FutureTask<Double> d: results)
//			System.out.println(d.get());
	}

	String data;

	public EncryptPerformanceTest() {
		data = generateData(10);
	}

	public double encryptTest() throws Exception {
		double totalTime = 0;
		long t1 = System.currentTimeMillis();
		for (int i = 0; i < times; i++)
			totalLength += encrypt(data, key).length();
		long t2 = System.currentTimeMillis();

		totalTime = (t2 - t1) / 1000.0;

		// print results.
//		System.out.printf(
//				"Data.Length:   %.2f MB.\nRunning Times: %d.\nOutput.Length: %.2f MB.\nExecution Time: %.2f s.\nEncrypt Speed: %.2f MB/s.\n",
//				data.length() / 1048576.0, times, totalLength / 1048576.0, totalTime,
//				times * data.length() / 1048576.0 / totalTime);

		return totalTime;
	}

	public String generateData(int sizeInMB) {
		StringBuilder sb = new StringBuilder();
		for (int size = 0; size < sizeInMB; size++) {
			for (int i = 0; i < 1024 * 64; i++)
				sb.append("Hello:0123456789");
		}
		return sb.toString();
	}

	public static String encrypt(String content, String key) throws Exception {
		SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec("1234567812345678".getBytes("utf-8")));
		byte[] bytes = cipher.doFinal(content.getBytes());
		String base64 = java.util.Base64.getEncoder().encodeToString(bytes);
		return base64;
	}

	@Override
	public Double call() throws Exception {
		long t1 = System.currentTimeMillis();
		for (int i = 0; i < times; i++) {
			totalLength += data.length();
			encrypt(data, key);
		}
		long t2 = System.currentTimeMillis();
		latch.countDown();
		return (double) (t2 - t1);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章