Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
UUoCのベンチマークです。 https://ja.stackoverflow.com/questions/34214

実験環境

  • Intel Core i7-7500U CPU @ 2.70 GHz クアッドコア
  • メモリ 16GB
  • Ubuntu 16.10 yakkety (x86_64, 4.8.0-46-generic)
  • GNU bash 4.3.46(1)-release (x86_64-pc-linux-gnu)
  • grep (GNU grep) 2.25
  • cat (GNU coreutils) 8.25
  • go version go1.8 linux/amd64
# 改行があるテキストファイルの場合のログ
Size grep a FILE cat FILE | grep a
1 1628986.050000 2277017.950000
5 1371493.850000 1866161.350000
10 1330203.100000 1663005.050000
50 1336509.300000 1693194.800000
100 1371718.000000 1811099.450000
500 1456991.150000 1917038.800000
1024 1543473.000000 2094624.000000
5120 2423058.550000 3364557.450000
10240 3218446.000000 4969714.750000
51200 11629891.200000 18146762.950000
102400 22254559.750000 34036223.300000
512000 100217975.550000 160507865.500000
1048576 180088340.850000 320137904.100000
5242880 857794564.150000 1545226725.900000
10485760 2886427989.250000 3202013808.850000
# バイナリファイルの場合のログ
Size grep a FILE cat FILE | grep a
1 1581347.050000 1775962.650000
5 1318343.850000 1761388.000000
10 1200220.150000 1554791.000000
50 1245887.950000 1578335.350000
100 1287939.950000 1702699.150000
500 1524866.950000 1842490.650000
1024 1859444.100000 2228896.900000
5120 3996075.150000 4256021.300000
10240 6442738.800000 6835296.600000
51200 25735508.400000 27734911.800000
102400 50883223.100000 52917631.950000
512000 246976414.400000 265936897.700000
1048576 504907376.700000 565962037.050000
5242880 2521654671.250000 2848791126.000000
10485760 5250627603.900000 5524435772.300000
# 改行があるテキストファイルについて、<FILENAME grep a についても同様にベンチマークをとってみたログ
Size <FILENAME grep a
1 2125799.150000
5 1830172.500000
10 1370422.950000
50 1421713.500000
100 1487108.450000
500 1606865.500000
1024 1631634.950000
5120 2442890.650000
10240 3453758.200000
51200 12332587.350000
102400 20900270.400000
512000 90421090.200000
1048576 194268279.050000
5242880 884363476.950000
10485760 3099899414.700000
# 改行が無いテキストファイルの場合のログ
Size grep a FILE cat FILE | grep a
1 1562107.050000 1911358.450000
5 1435588.650000 2015130.550000
10 1283699.150000 1560620.800000
50 1287053.950000 1629947.300000
100 1330382.350000 1635569.650000
500 1880728.450000 2145010.250000
1024 2600131.250000 3162551.900000
5120 7538146.500000 11759352.200000
10240 12450896.600000 31949892.750000
51200 46581310.000000 506808350.150000
102400 89835399.050000 1984445186.600000
512000 489720105.050000 46670393357.750000
1048576 1133701684.900000 195539025232.200012
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"syscall"
"time"
)
const KB int64 = 1
const MB int64 = 1024
const GB int64 = 1024 * 1024
func main() {
fmt.Printf("Size\tgrep a FILE\tcat FILE | grep a\n")
sizes := []int64{1 * KB, 5 * KB, 10 * KB, 50 * KB, 100 * KB, 500 * KB,
1 * MB, 5 * MB, 10 * MB, 50 * MB, 100 * MB, 500 * MB,
1 * GB, 5 * GB, 10 * GB}
n := 10
for _, size := range sizes {
benchmark(size, n)
}
}
func benchmark(size int64, n int) {
// 指定サイズのファイルを作る
bigFile, err := ioutil.TempFile("", "")
if err != nil {
log.Fatal(err)
}
bigFileName := bigFile.Name()
defer func() {
err := os.Remove(bigFileName)
if err != nil {
log.Fatal(err)
}
}()
/*
if err := bigFile.Truncate(size * 1024); err != nil {
log.Fatal(err)
}
*/
// ここでベンチマークの種類を変えます
fillZero(bigFile, size)
// 2*n 回時間計測して平均をとる
var timeSum1 time.Duration = 0
var timeSum2 time.Duration = 0
timeSum1 += execLoop(n, grep1, bigFileName)
timeSum2 += execLoop(n, grep2, bigFileName)
timeSum2 += execLoop(n, grep2, bigFileName)
timeSum1 += execLoop(n, grep1, bigFileName)
// 出力
fmt.Printf("%d\t%f\t%f\n", size,
float64(timeSum1)*0.5/float64(n),
float64(timeSum2)*0.5/float64(n))
}
func fillZero(file *os.File, size int64) {
b := make([]byte, 1024)
for i, _ := range b {
b[i] = '0'
}
for i := int64(0); i < size; i++ {
_, err := file.Write(b)
if err != nil {
// TODO
log.Fatal(err)
}
}
}
func fillZeroWithNewline(file *os.File, size int64) {
b := make([]byte, 1024)
for i := 0; i < 1023; i++ {
b[i] = '0'
}
b[1023] = '\n'
for i := int64(0); i < size; i++ {
_, err := file.Write(b)
if err != nil {
// TODO
log.Fatal(err)
}
}
}
func fillNull(file *os.File, size int64) {
b := make([]byte, 1024)
for i, _ := range b {
b[i] = 0x0
}
for i := int64(0); i < size; i++ {
_, err := file.Write(b)
if err != nil {
// TODO
log.Fatal(err)
}
}
}
// grep を n 回ループする時間を測る
func execLoop(n int, grep func(string) string, bigFileName string) time.Duration {
var timeSum time.Duration = 0
for i := 0; i < n; i++ {
command := exec.Command("bash", "-c", grep(bigFileName))
start := time.Now()
err := command.Run()
timeSum += time.Since(start)
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
if status.ExitStatus() != 1 {
log.Fatal(err)
}
} else {
log.Fatalf("exitErr.Sys().(syscall.WaitStatus) failed")
}
} else {
log.Fatal(err)
}
}
}
return timeSum
}
// grep a FILENAME
func grep1(fileName string) string {
return "grep a \"" + fileName + "\""
}
// cat FILENAME | grep a
func grep2(fileName string) string {
return "cat \"" + fileName + "\" | grep a"
}
set terminal png font "MigMix 2M,14"
set title "Useless Use of Catによる実行速度変化 (改行あり)"
set xlabel "テキストファイルのサイズ [KB]"
set ylabel "時間 [秒]"
set key left top
set output "UUoC.png"
set logscale x 10
set logscale y 10
set format x "%.0t{/Symbol \264}10^{%T}"
set format y "%.0t{/Symbol \264}10^{%T}"
set xtics rotate by -70
plot "log" using 1:($2 / 1000000000) title "grep a FILENAME", \
"log" using 1:($3 / 1000000000) title "cat FILENAME | grep a"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment