Pythonのパフォーマンス確認 †Pythonの forループは遅いらしく「リスト内包表記」や 「mapの利用」を促す記事が多く目につくが、 結果 †先に結果を書いてしまうと、素のforループ等は Java と比べるとかなり遅い事がわかる。スクリプト言語の限界か・・ ※環境:「2 GHz Intel Core i7、コア数: 2、メモリ: 8GB」にて確認。
Python †forループ †# coding: utf-8 import time from statistics import mean # チェックは100回実施 results = [] for i in range(100): # forチェック(100万回繰り返す) stime = time.time() count = 0 for j in range(1000000): count += 1 etime = time.time() results.append(etime - stime) # 結果から最速、最遅を除く min_result = min(results) max_result = max(results) summary = [] for result in results: if result != max_result and result != min_result: summary.append(result) # 最速、最遅、平均を出力 print(f'種別\t最速\t最遅\t平均\t補足') print(f'Python\tfor loop\t{int(min(summary)*1000)}\t{int(max(summary)*1000)}\t{int(mean(summary)*1000)}\t100万回ループ') whileループ †# coding: utf-8 import time from statistics import mean # チェックは100回実施 results = [] for i in range(100): # forチェック(100万回繰り返す) end_index = 1000000 count = 0 stime = time.time() while True: count += 1 if count >= end_index: break etime = time.time() results.append(etime - stime) # 結果から最速、最遅を除く min_result = min(results) max_result = max(results) summary = [] for result in results: if result != max_result and result != min_result: summary.append(result) # 最速、最遅、平均を出力 print(f'種別\t最速\t最遅\t平均\t補足') print(f'Python\twhile loop\t{int(min(summary)*1000)}\t{int(max(summary)*1000)}\t{int(mean(summary)*1000)}\t100万回ループ') list参照 †# coding: utf-8 import time import random from statistics import mean # 参照元となるlistを作成する list1 = [ random.randrange(0,1000000) for i in range(1000000)] # チェックは100回実施 results = [] for i in range(100): # 1万回の集計値を取得 all_times = 0 for j in range(10000): target_index = random.randrange(0, 1000000 - 1) stime = time.time() ref_value = list1[target_index] etime = time.time() diff = etime - stime all_times += diff results.append(all_times) # 結果から最速、最遅を除く min_result = min(results) max_result = max(results) summary = [] for result in results: if result != max_result and result != min_result: summary.append(result) # 最速、最遅、平均を出力 print(f'種別\t最速\t最遅\t平均\t補足') print(f'Python\tlist ref\t{int(min(summary)*1000)}\t{int(max(summary)*1000)}\t{int(mean(summary)*1000)}\t1万回分の合算値') dict参照 †# coding: utf-8 import time import random from statistics import mean # 参照元となるdictを作成する dict1 = dict(map(lambda i: (f'test{i}', random.randrange(0,1000000)), list(range(1000000)))) # チェックは100回実施 results = [] for i in range(100): # 1万回の集計値を取得 all_times = 0 for j in range(10000): target_index = random.randrange(0, 1000000 - 1) stime = time.time() target_key = f'test_{target_index}' ref_value = None if target_key not in dict1: dict1[target_key] = None ref_value = dict1[target_key] etime = time.time() diff = etime - stime all_times += diff results.append(all_times) # 結果から最速、最遅を除く min_result = min(results) max_result = max(results) summary = [] for result in results: if result != max_result and result != min_result: summary.append(result) # 最速、最遅、平均を出力 print(f'種別\t最速\t最遅\t平均\t補足') print(f'Python\tdict ref\t{int(min(summary)*1000)}\t{int(max(summary)*1000)}\t{int(mean(summary)*1000)}\t1万回の合算値') Java †forループ †import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class App { public static void main(String[] args) { try { forLoop(); } catch (Exception e) { e.printStackTrace(); } } public static void forLoop() { List<Long> results = new ArrayList<Long>(); // チェックは100回実施 for (int i = 0; i < 100; i++) { // forチェック(1億回繰り返す) ※100万回程度だと計測にならない int count = 0; long stime = System.currentTimeMillis(); //long stime = System.nanoTime(); //for (int j = 0; j < 1000000; j++) { for (long j = 0; j < 100000000; j++) { count++; } long etime = System.currentTimeMillis(); //long etime = System.nanoTime(); results.add(etime - stime); //System.out.println(etime - stime); } // GCがなければバラツキが殆ど無いようなので除外しない final List<Long> summary = results; /* // 結果から最速、最遅を除く final List<Long> summary = new ArrayList<Long>(); { final long min = results.stream().min((a, b) -> a.compareTo(b)).get(); final long max = results.stream().max((a, b) -> a.compareTo(b)).get(); //results.forEach(num -> { if ((num != min) && (num != max)){ summary.add(num);} }); results.forEach(num -> { summary.add(num); }); } */ // 最速、最遅、平均を出力 final long min = summary.stream().min((a, b) -> a.compareTo(b)).get(); final long max = summary.stream().max((a, b) -> a.compareTo(b)).get(); final long sum = summary.stream().mapToLong(num -> num).sum(); //System.out.println("Java\tfor loop\t最速\t最遅\t平均\t補足"); System.out.println("Java\tfor loop\t" + min/100.0 + "\t" + max/100.0 + "\t" + (sum/summary.size()/100.0) + "\t1億回ループで計測し100分の1にしたもの"); } } whileループ †import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class App { public static void main(String[] args) { try { whileLoop(); } catch (Exception e) { e.printStackTrace(); } } public static void whileLoop() { List<Long> results = new ArrayList<Long>(); // チェックは100回実施 for (int i = 0; i < 100; i++) { // forチェック(1億回繰り返す) ※100万回程度だと計測にならない int count = 0; long stime = System.currentTimeMillis(); int endIndex = 100000000;; while (true) { count++; if (count >= endIndex) { break; } } long etime = System.currentTimeMillis(); results.add(etime - stime); } // GCがなければバラツキが殆ど無いようなので除外しない final List<Long> summary = results; /* // 結果から最速、最遅を除く final List<Long> summary = new ArrayList<Long>(); { final long min = results.stream().min((a, b) -> a.compareTo(b)).get(); final long max = results.stream().max((a, b) -> a.compareTo(b)).get(); //results.forEach(num -> { if ((num != min) && (num != max)){ summary.add(num);} }); results.forEach(num -> { summary.add(num); }); } */ // 最速、最遅、平均を出力 final long min = summary.stream().min((a, b) -> a.compareTo(b)).get(); final long max = summary.stream().max((a, b) -> a.compareTo(b)).get(); final long sum = summary.stream().mapToLong(num -> num).sum(); //System.out.println("Java\tfor loop\t最速\t最遅\t平均\t補足"); System.out.println("Java\twhile loop\t" + min/100.0 + "\t" + max/100.0 + "\t" + (sum/summary.size()/100.0) + "\t1億回ループで計測し100分の1にしたもの"); } } List参照 †import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class App { public static void main(String[] args) { try { listRef(); } catch (Exception e) { e.printStackTrace(); } } public static void listRef(){ List<Long> results = new ArrayList<Long>(); // チェックは100回実施 for (int i = 0; i < 100; i++) { // 参照元となるListを作成する List<Long> list1 = new ArrayList<Long>(); for (int j = 0; j < 1000000; j++) { list1.add(Math.round(Math.random() * 1000000)); } // 1万回の集計値を取得 long allTimes = 0; for (int j = 0; j < 10000; j++) { int index = new Long(Math.round(Math.abs(Math.random() * 1000000) - 1)).intValue(); long stime = System.currentTimeMillis(); Long num = list1.get(index); long etime = System.currentTimeMillis(); allTimes = allTimes + (etime - stime); } results.add(allTimes); } // GCがなければバラツキが殆ど無いようなので除外しない final List<Long> summary = results; /* // 結果から最速、最遅を除く final List<Long> summary = new ArrayList<Long>(); { final long min = results.stream().min((a, b) -> a.compareTo(b)).get(); final long max = results.stream().max((a, b) -> a.compareTo(b)).get(); //results.forEach(num -> { if ((num != min) && (num != max)){ summary.add(num);} }); results.forEach(num -> { summary.add(num); }); } */ // 最速、最遅、平均を出力 final long min = summary.stream().min((a, b) -> a.compareTo(b)).get(); final long max = summary.stream().max((a, b) -> a.compareTo(b)).get(); final long sum = summary.stream().mapToLong(num -> num).sum(); //System.out.println("Java\tfor loop\t最速\t最遅\t平均\t補足"); System.out.println("Java\tlist ref\t" + min + "\t" + max + "\t" + (sum/summary.size()) + "\t1万回分の合算値"); } } Map参照 †import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class App { public static void main(String[] args) { try { mapRef(); } catch (Exception e) { e.printStackTrace(); } } public static void mapRef(){ List<Long> results = new ArrayList<Long>(); // チェックは100回実施 for (int i = 0; i < 100; i++) { // 参照元となるMapを作成する Map<String,Long> map1 = new HashMap<String,Long>(); for (int j = 0; j < 1000000; j++) { map1.put("test"+Math.round(Math.random() * 1000000), Math.round(Math.random() * 1000000)); } // 1万回の集計値を取得 long allTimes = 0; for (int j = 0; j < 10000; j++) { String key = "test" + Math.round(Math.abs(Math.random() * 1000000)); long stime = System.currentTimeMillis(); if (!map1.containsKey(key)) { map1.put(key, null); } Long num = map1.get(key); long etime = System.currentTimeMillis(); allTimes = allTimes + (etime - stime); } results.add(allTimes); } // GCがなければバラツキが殆ど無いようなので除外しない final List<Long> summary = results; /* // 結果から最速、最遅を除く final List<Long> summary = new ArrayList<Long>(); { final long min = results.stream().min((a, b) -> a.compareTo(b)).get(); final long max = results.stream().max((a, b) -> a.compareTo(b)).get(); //results.forEach(num -> { if ((num != min) && (num != max)){ summary.add(num);} }); results.forEach(num -> { summary.add(num); }); } */ // 最速、最遅、平均を出力 final long min = summary.stream().min((a, b) -> a.compareTo(b)).get(); final long max = summary.stream().max((a, b) -> a.compareTo(b)).get(); final long sum = summary.stream().mapToLong(num -> num).sum(); //System.out.println("Java\tfor loop\t最速\t最遅\t平均\t補足"); System.out.println("Java\tmap ref\t" + min + "\t" + max + "\t" + (sum/summary.size()) + "\t1万回分の合算値"); } } Pythonのチューニング †Pythonのチューニング を参照 |