Skip to content

Commit

Permalink
v0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
showwin committed Nov 4, 2015
1 parent b2d7079 commit 64aab17
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 73 deletions.
98 changes: 90 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# speedtest-go
Command Line Interface to Test Internet Speed using [speedtest.net](http://www.speedtest.net/)
Command Line Interface to Test Internet Speed using [speedtest.net](http://www.speedtest.net/).

You can speedtest 2x faster than [speedtest.net](http://www.speedtest.net/); nevertheless results are almost the same.
[see experimental results]()

Inspired by [sivel/speedtest-cli](https://github.com/sivel/speedtest-cli)

Expand All @@ -14,6 +17,9 @@ $ brew update
$ brew upgrate speedtest
```

### Others (Linux, Windows, etc.)
Please download compatible package from [Releases](https://github.com/showwin/speedtest-go/releases)

## Usage
```
$ speedtest --help
Expand All @@ -27,14 +33,90 @@ Flags:
--version Show application version.
```

**Select Closest Server by Default**
![](https://github.com/showwin/speedtest-go/blob/master/docs/images/usage.png)
#### Select Closest Server by Default
```
$ speedtest
Testing From IP: 124.27.199.165 (Fujitsu) [34.9769, 138.3831]
Target Server: [6691] 9.03km Shizuoka (Japan) by sudosan
latency: 39.436061ms
Download Test: ................
Upload Test: ................
Download: 73.30 Mbit/s
Upload: 35.26 Mbit/s
```

#### Show Available Servers
```
$ speedtest --list
Testing From IP: 124.27.199.165 (Fujitsu) [34.9769, 138.3831]
[6691] 9.03km Shizuoka (Japan) by sudosan
[6087] 120.55km Fussa-shi (Japan) by Allied Telesis Capital Corporation
[6508] 125.44km Yokohama (Japan) by at2wn
[6424] 148.23km Tokyo (Japan) by Cordeos Corp.
[6492] 153.06km Sumida (Japan) by denpa893
[7139] 192.63km Tsukuba (Japan) by SoftEther Corporation
[6368] 194.83km Maibara (Japan) by gatolabo
[6463] 220.39km Kusatsu (Japan) by j416dy
[6766] 232.54km Nomi (Japan) by JAIST(ino-lab)
[6476] 265.10km Osaka (Japan) by rxy (individual)
[6477] 268.94km Sakai (Japan) by satoweb
```

#### Select Multiple Servers by Server ID
```
$ speedtest --server 6691 --server 6087
Testing From IP: 124.27.199.165 (Fujitsu) [34.9769, 138.3831]
Target Server: [6691] 9.03km Shizuoka (Japan) by sudosan
latency: 23.612861ms
Download Test: ................
Upload Test: ........
Target Server: [6087] 120.55km Fussa-shi (Japan) by Allied Telesis Capital Corporation
latency: 38.694699ms
Download Test: ................
Upload Test: ................
[6691] Download: 65.82 Mbit/s, Upload: 27.00 Mbit/s
[6087] Download: 72.24 Mbit/s, Upload: 29.56 Mbit/s
Download Avg: 69.03 Mbit/s
Upload Avg: 28.28 Mbit/s
```

## Summary of Experimental Results
Speedtest-go is a great tool because of following 2 reasons:
* Testing time is the **SHORTEST** compare to [speedtest.net](http://www.speedtest.net/) and [sivel/speedtest-cli](https://github.com/sivel/speedtest-cli), especially about 2x faster then [speedtest.net](http://www.speedtest.net/).
* Result is **MORE CLOSE** to [speedtest.net](http://www.speedtest.net/) than [speedtest-cli](https://github.com/sivel/speedtest-cli).

Following data is summarized. If you got interest in, please see [more details]().

### Download (Mbps)

| distance(km) | speedtest.net | speedtest-go | speedtest-cli |
| :-- | :--: | :--: | :--: |
| 0 - 1000 | 92.12 | **91.21** | 70.27 |
| 1000 - 8000 | 66.45 | **65.51** | 56.56 |
| 8000 - 20000 | 11.84 | 9.43 | **11.87** |

### Upload (Mbps)

| distance(km) | speedtest.net | speedtest-go | speedtest-cli |
| :-- | :--: | :--: | :--: |
| 0 - 1000 | 65.56 | **47.58** | 36.16 |
| 1000 - 8000 | 58.02 | **54.74** | 26.78 |
| 8000 - 20000 | 5.20 | 8.32 | **2.58** |

### Testing Time (sec)

**Show Available Servers**
![](https://github.com/showwin/speedtest-go/blob/master/docs/images/usage_list.png)
| distance(km) | speedtest.net | speedtest-go | speedtest-cli |
| :-- | :--: | :--: | :--: |
| 0 - 1000 | 45.03 | **22.84** | 24.46 |
| 1000 - 8000 | 44.89 | **24.45** | 28.52 |
| 8000 - 20000 | 49.64 | **34.08** | 41.26 |

**Select Multiple Servers with Server ID**
![](https://github.com/showwin/speedtest-go/blob/master/docs/images/usage_multi_servers.png)
## LICENSE

##LICENSE
[MIT](https://github.com/showwin/speedtest-go/blob/master/LICENSE)
41 changes: 41 additions & 0 deletions docs/experimental_result.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Experimental Result
I randomly select 9 servers to speedtest considering distance from my house. Try speedtesting twice to each server. Testing order is like [speedtest.net] -> [speedtest-go] -> [speedtest-cli] -> [speedtest-cli] -> [speedtest-go] -> [speedtest.net]. To the next server, starting from [speedtest-go], like [speedtest-go] -> [speedtest-cli] -> [speedtest.net] -> [speedtest.net] -> ….

## Downlaod (Mbps)
| distance(km) | server id | speediest.net (test1) | speediest.net (test2) | speedtest-go (test1) | speedtest-go (test2) | speedtest-cli (test1) | speedtest-cli (test2) |
| :-- | :--: | :--: | :--: | :--: |
| 0 - 1000 (9km) | 6691 | 93.34 | 93.51 | 89.13 | 88.40 | 88.21 | 83.34 |
| 0 - 1000 (194km) | 6368 | 93.45 | 94.20 | 92.93 | 92.26 | 88.45 | 77.07 |
| 0 - 1000 (865km) | 6842 | 88.31 | 89.91 | 91.26 | 93.30 | 67.33 | 87.52 |
| 1000 - 8000 (1982km) | 2589 | 90.24 | 94.05 | 79.61 | 79.52 | 79.16 | 70.36 |
| 1000 - 8000 (4801km) | 3296 | 75.61 | 52.83 | 69.89 | 69.86 | 58.19 | 55.93 |
| 1000 - 8000 (6627km) | 1718 | 42.04 | 43.92 | 39.81 | 54.35 | 44.47 | 31.27 |
| 8000 - 20000 (8972km) | 3409 | 22.11 | 22.74 | 28.21 | 21.82 | 24.78 | 30.59 |
| 8000 - 20000 (13781km) | 3162 | 15.78 | 7.73 | 1.94 | 1.02 | 3.32 | 2.40 |
| 8000 - 20000 (17805km) | 4256 | 1.15 | 1.50 | 1.79 | 1.79 | 6.41 | 3.69 |

## Upload (Mbps)
| distance(km) | server id | speediest.net (test1) | speediest.net (test2) | speedtest-go (test1) | speedtest-go (test2) | speedtest-cli (test1) |
| :-- | :--: | :--: | :--: | :--: |
| 0 - 1000 (9km) | 6691 | 52.03 | 48.82 | 40.72 | 43.84 | 36.03 | 36.21
| 0 - 1000 (194km) | 6368 | 78.30 | 66.92 | 53.98 | 44.07 | 37.26 | 46.98
| 0 - 1000 (865km) | 6842 | 65.34 | 81.96 | 50.27 | 52.57 | 29.42 | 31.08
| 1000 - 8000 (1982km) | 2589 | 89.29 | 58.69 | 80.68 | 56.59 | 42.66 | 44.34
| 1000 - 8000 (4801km) | 3296 | 50.16 | 50.78 | 54.94 | 54.18 | 20.59 | 20.23
| 1000 - 8000 (6627km) | 1718 | 48.48 | 50.71 | 39.81 | 42.21 | 16.16 | 16.72
| 8000 - 20000 (8972km) | 3409 | 18.07 | 20.30 | 20.35 | 24.92 | 5.87 | 3.37
| 8000 - 20000 (13781km) | 3162 | 1.45 | 0.33 | 1.78 | 0.77 | 1.08 | 1.34
| 8000 - 20000 (17805km) | 4256 | 1.16 | 0.30 | 1.00 | 1.11 | 2.37 | 1.42

## Testing Time (sec)
| distance(km) | server id | speediest.net (test1) | speediest.net (test2) | speedtest-go (test1) | speedtest-go (test2) | speedtest-cli (test1) |
| :-- | :--: | :--: | :--: | :--: |
| 0 - 1000 (9km) | 6691 | 44.87 | 45.76 | 24.45 | 22.40 | 20.82 | 16.51
| 0 - 1000 (194km) | 6368 | 43.85 | 42.97 | 19.60 | 22.36 | 22.25 | 24.01
| 0 - 1000 (865km) | 6842 | 46.62 | 46.12 | 21.83 | 26.40 | 39.07 | 24.10
| 1000 - 8000 (1982km) | 2589 | 45.38 | 44.18 | 18.71 | 21.35 | 26.15 | 25.71
| 1000 - 8000 (4801km) | 3296 | 47.92 | 50.52 | 24.71 | 23.47 | 32.07 | 28.53
| 1000 - 8000 (6627km) | 1718 | 40.15 | 41.16 | 28.05 | 30.42 | 31.01 | 27.65
| 8000 - 20000 (8972km) | 3409 | 51.53 | 56.89 | 38.13 | 41.55 | 36.87 | 34.47
| 8000 - 20000 (13781km) | 3162 | 52.75 | 58.10 | 28.78 | 29.91 | 40.75 | 46.88
| 8000 - 20000 (17805km) | 4256 | 37.73 | 40.82 | 33.33 | 32.79 | 37.82 | 50.78
Binary file removed docs/images/usage.png
Binary file not shown.
Binary file removed docs/images/usage_list.png
Binary file not shown.
Binary file removed docs/images/usage_multi_servers.png
Binary file not shown.
132 changes: 78 additions & 54 deletions request.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@ var dlSizes = [...]int{350, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000}
var ulSizes = [...]int{100, 300, 500, 800, 1000, 1500, 2500, 3000, 3500, 4000} //kB
var client = http.Client{}

func DownloadTest(sUrl string) float64 {
func DownloadTest(sUrl string, latency time.Duration) float64 {
dlUrl := strings.Split(sUrl, "/upload")[0]
latency := pingTest(sUrl)
fmt.Printf("Download WarmUp: ")
fmt.Printf("Download Test: ")
wg := new(sync.WaitGroup)

// worm up
// Warming up
sTime := time.Now()
for i := 0; i < 2; i++ {
wg.Add(1)
Expand All @@ -30,40 +29,49 @@ func DownloadTest(sUrl string) float64 {
wg.Wait()
fTime := time.Now()
// 1.125MB for each request (750 * 750 * 2)
speed := 1.125 * 8 * 2 / fTime.Sub(sTime.Add(latency)).Seconds()
fmt.Printf("%5.2f Mbit/s\n", speed)
wuSpeed := 1.125 * 8 * 2 / fTime.Sub(sTime.Add(latency)).Seconds()

// decide workload by warm up speed
// Decide workload by warm up speed
workload := 0
if 10.0 < speed {
weight := 0
skip := false
if 10.0 < wuSpeed {
workload = 16
} else if 1.0 < speed {
weight = 4
} else if 4.0 < wuSpeed {
workload = 8
} else {
weight = 4
} else if 2.5 < wuSpeed {
workload = 4
weight = 4
} else {
skip = true
}

// speedtest
fmt.Printf("Download Test: ")
sTime = time.Now()
for i := 0; i < workload; i++ {
wg.Add(1)
go downloadRequest(wg, dlUrl)
// Main speedtest
dlSpeed := wuSpeed
if skip == false {
sTime = time.Now()
for i := 0; i < workload; i++ {
wg.Add(1)
go downloadRequest(wg, dlUrl, weight)
}
wg.Wait()
fTime = time.Now()
fmt.Printf("\n")

reqMB := dlSizes[weight] * dlSizes[weight] * 2 / 1000 / 1000
dlSpeed = float64(reqMB) * 8 * float64(workload) / fTime.Sub(sTime).Seconds()
}
wg.Wait()
fTime = time.Now()
fmt.Printf("\n")

// 4.5MB for each request (width(1500) * height(1500) * 2)
return 4.5 * 8 * float64(workload) / fTime.Sub(sTime).Seconds()
return dlSpeed
}

func UploadTest(sUrl string) float64 {
latency := pingTest(sUrl)
fmt.Printf("Upload WarmUp: ")
func UploadTest(sUrl string, latency time.Duration) float64 {
fmt.Printf("Upload Test: ")
wg := new(sync.WaitGroup)

// worm up
// Warm up
sTime := time.Now()
wg = new(sync.WaitGroup)
for i := 0; i < 2; i++ {
Expand All @@ -73,39 +81,50 @@ func UploadTest(sUrl string) float64 {
wg.Wait()
fTime := time.Now()
// 1.0 MB for each request
speed := 1.0 * 8 * 2 / fTime.Sub(sTime.Add(latency)).Seconds()
fmt.Printf("%5.2f Mbit/s\n", speed)
wuSpeed := 1.0 * 8 * 2 / fTime.Sub(sTime.Add(latency)).Seconds()

// decide workload by warm up speed
// Decide workload by warm up speed
workload := 0
if 10.0 < speed {
weight := 0
skip := false
if 10.0 < wuSpeed {
workload = 16
} else if 1.0 < speed {
weight = 9
} else if 4.0 < wuSpeed {
workload = 8
} else {
weight = 9
} else if 2.5 < wuSpeed {
workload = 4
weight = 5
} else {
skip = true
}

// speedtest
fmt.Printf("Upload Test: ")
sTime = time.Now()
for i := 0; i < workload; i++ {
wg.Add(1)
go uploadRequest(wg, sUrl)
// Main speedtest
ulSpeed := wuSpeed
if skip == false {
sTime = time.Now()
for i := 0; i < workload; i++ {
wg.Add(1)
go uploadRequest(wg, sUrl, weight)
}
wg.Wait()
fTime = time.Now()
fmt.Printf("\n")

reqMB := float64(ulSizes[weight]) / 1000
ulSpeed = reqMB * 8 * float64(workload) / fTime.Sub(sTime).Seconds()
}
wg.Wait()
fTime = time.Now()
fmt.Printf("\n")

// 4.0 MB for each request
return 4 * 8 * float64(workload) / fTime.Sub(sTime).Seconds()
return ulSpeed
}

func dlWarmUp(wg *sync.WaitGroup, dlUrl string) {
size := dlSizes[2]
url := dlUrl + "/random" + strconv.Itoa(size) + "x" + strconv.Itoa(size) + ".jpg"

resp, _ := client.Get(url)
resp, err := client.Get(url)
CheckError(err)
defer resp.Body.Close()
ioutil.ReadAll(resp.Body)

Expand All @@ -117,51 +136,56 @@ func ulWarmUp(wg *sync.WaitGroup, ulUrl string) {
v := url.Values{}
v.Add("content", strings.Repeat("0123456789", size*100-51))

resp, _ := client.PostForm(ulUrl, v)
resp, err := client.PostForm(ulUrl, v)
CheckError(err)
defer resp.Body.Close()
ioutil.ReadAll(resp.Body)

wg.Done()
}

func downloadRequest(wg *sync.WaitGroup, dlUrl string) {
size := dlSizes[4]
func downloadRequest(wg *sync.WaitGroup, dlUrl string, w int) {
size := dlSizes[w]
url := dlUrl + "/random" + strconv.Itoa(size) + "x" + strconv.Itoa(size) + ".jpg"

resp, _ := client.Get(url)
resp, err := client.Get(url)
CheckError(err)
defer resp.Body.Close()
ioutil.ReadAll(resp.Body)

fmt.Printf(".")
wg.Done()
}

func uploadRequest(wg *sync.WaitGroup, ulUrl string) {
func uploadRequest(wg *sync.WaitGroup, ulUrl string, w int) {
size := ulSizes[9]
v := url.Values{}
v.Add("content", strings.Repeat("0123456789", size*100-51))

resp, _ := client.PostForm(ulUrl, v)
resp, err := client.PostForm(ulUrl, v)
CheckError(err)
defer resp.Body.Close()
ioutil.ReadAll(resp.Body)

fmt.Printf(".")
wg.Done()
}

func pingTest(sUrl string) time.Duration {
func PingTest(sUrl string) time.Duration {
pingUrl := strings.Split(sUrl, "/upload")[0] + "/latency.txt"

l := time.Duration(0)
l := time.Duration(100000000000) // 10sec
for i := 0; i < 3; i++ {
sTime := time.Now()
resp, err := http.Get(pingUrl)
fTime := time.Now()
CheckError(err)
defer resp.Body.Close()
l = l + fTime.Sub(sTime)
if fTime.Sub(sTime) < l {
l = fTime.Sub(sTime)
}
}

fmt.Println("latency:", (l / 6.0))
return l / 6.0
fmt.Println("latency:", (l / 2.0))
return l / 2.0
}
Loading

0 comments on commit 64aab17

Please sign in to comment.