-
-
Save z-sector/2a6abebc58993ad047960c17bc403fe1 to your computer and use it in GitHub Desktop.
Revisions
-
Montana Flynn revised this gist
Dec 23, 2016 . 1 changed file with 40 additions and 47 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -24,12 +24,12 @@ func boundedParallelGet(urls []string, concurrencyLimit int) []result { semaphoreChan := make(chan struct{}, concurrencyLimit) // this channel will not block and collect the http request results resultsChan := make(chan *result) // make sure we close these channels when we're done with them defer func() { close(semaphoreChan) close(resultsChan) }() // keen an index and loop through every url we will send a request to @@ -49,9 +49,8 @@ func boundedParallelGet(urls []string, concurrencyLimit int) []result { res, err := http.Get(url) result := &result{i, *res, err} // now we can send the result struct through the resultsChan resultsChan <- result // once we're done it's we read from the semaphoreChan which // has the effect of removing one from the limit and allowing @@ -64,11 +63,10 @@ func boundedParallelGet(urls []string, concurrencyLimit int) []result { // make a slice to hold the results we're expecting var results []result // start listening for any results over the resultsChan // once we get a result append it to the result slice for { result := <-resultsChan results = append(results, *result) // if we've reached the expected amount of urls then stop @@ -82,50 +80,45 @@ func boundedParallelGet(urls []string, concurrencyLimit int) []result { return results[i].index < results[j].index }) // now we're done we return the results return results } // we'll use the init function to set up the benchmark // by making a slice of 100 URLs to send requets to var urls []string func init() { for i := 0; i < 100; i++ { urls = append(urls, "http://httpbin.org/get") } } // the main function sets up an anonymous benchmark func // that will time how long it takes to get all the URLs // at the specified concurrency level // // and you should see something like the following printed // depending on how fast your computer and internet is // // 5 bounded parallel requests: 100/100 in 5.533223255 // 10 bounded parallel requests: 100/100 in 2.5115351219 // 25 bounded parallel requests: 100/100 in 1.189462884 // 50 bounded parallel requests: 100/100 in 1.17430002 // 75 bounded parallel requests: 100/100 in 1.001383863 // 100 bounded parallel requests: 100/100 in 1.3769354 func main() { benchmark := func(urls []string, concurrency int) string { startTime := time.Now() results := boundedParallelGet(urls, concurrency) seconds := time.Since(startTime).Seconds() tmplate := "%d bounded parallel requests: %d/%d in %v" return fmt.Sprintf(tmplate, concurrency, len(results), len(urls), seconds) } fmt.Println(benchmark(urls, 10)) fmt.Println(benchmark(urls, 25)) fmt.Println(benchmark(urls, 50)) fmt.Println(benchmark(urls, 75)) fmt.Println(benchmark(urls, 100)) } -
Montana Flynn revised this gist
Dec 23, 2016 . 1 changed file with 19 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -8,7 +8,7 @@ import ( ) // a struct to hold the result from each request including an index // which will be used for sorting the results after they come in type result struct { index int res http.Response @@ -26,6 +26,12 @@ func boundedParallelGet(urls []string, concurrencyLimit int) []result { // this channel will not block and collect the http request results resultChan := make(chan *result) // make sure we close these channels when we're done with them defer func() { close(semaphoreChan) close(resultChan) }() // keen an index and loop through every url we will send a request to for i, url := range urls { @@ -61,7 +67,7 @@ func boundedParallelGet(urls []string, concurrencyLimit int) []result { // start listening for any results over the resultChan for { // once we get a result append it to the result slice result := <-resultChan results = append(results, *result) @@ -103,10 +109,19 @@ func main() { fmt.Println(benchmarkBoundedParallelRequests(urls, 50)) fmt.Println(benchmarkBoundedParallelRequests(urls, 75)) fmt.Println(benchmarkBoundedParallelRequests(urls, 100)) fmt.Println(benchmarkBoundedParallelRequests(urls, 125)) fmt.Println(benchmarkBoundedParallelRequests(urls, 150)) fmt.Println(benchmarkBoundedParallelRequests(urls, 175)) fmt.Println(benchmarkBoundedParallelRequests(urls, 200)) fmt.Println(benchmarkBoundedParallelRequests(urls, 300)) fmt.Println(benchmarkBoundedParallelRequests(urls, 325)) fmt.Println(benchmarkBoundedParallelRequests(urls, 350)) fmt.Println(benchmarkBoundedParallelRequests(urls, 375)) fmt.Println(benchmarkBoundedParallelRequests(urls, 300)) // and you should see something like the following printed // depending on how fast your computer and internet is // 5 bounded parallel requests: 100/100 in 5.533223255 // 10 bounded parallel requests: 100/100 in 2.5115351219999997 // 25 bounded parallel requests: 100/100 in 1.189462884 -
Montana Flynn revised this gist
Dec 23, 2016 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -106,7 +106,7 @@ func main() { // and you should see something like the following printed // depending on how fast your computer and internet is // // 5 bounded parallel requests: 100/100 in 5.533223255 // 10 bounded parallel requests: 100/100 in 2.5115351219999997 // 25 bounded parallel requests: 100/100 in 1.189462884 -
Montana Flynn revised this gist
Dec 23, 2016 . 1 changed file with 11 additions and 11 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -96,21 +96,21 @@ func main() { urls = append(urls, "http://httpbin.org/get") } // and now let's compare different concurrency limits fmt.Println(benchmarkBoundedParallelRequests(urls, 5)) fmt.Println(benchmarkBoundedParallelRequests(urls, 10)) fmt.Println(benchmarkBoundedParallelRequests(urls, 25)) fmt.Println(benchmarkBoundedParallelRequests(urls, 50)) fmt.Println(benchmarkBoundedParallelRequests(urls, 75)) fmt.Println(benchmarkBoundedParallelRequests(urls, 100)) // and you should see something like the following printed // depending on how fast your computer and internet is // 5 bounded parallel requests: 100/100 in 5.533223255 // 10 bounded parallel requests: 100/100 in 2.5115351219999997 // 25 bounded parallel requests: 100/100 in 1.189462884 // 50 bounded parallel requests: 100/100 in 1.17430002 // 75 bounded parallel requests: 100/100 in 1.001383863 // 100 bounded parallel requests: 100/100 in 1.3769354 } -
Montana Flynn revised this gist
Dec 23, 2016 . 1 changed file with 6 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -96,21 +96,21 @@ func main() { urls = append(urls, "http://httpbin.org/get") } fmt.Println(benchmarkBoundedParallelRequests(urls, 5)) // Output: 5 bounded parallel requests: 100/100 in 5.533223255 fmt.Println(benchmarkBoundedParallelRequests(urls, 10)) // Output: 10 bounded parallel requests: 100/100 in 2.5115351219999997 fmt.Println(benchmarkBoundedParallelRequests(urls, 25)) // Output: 25 bounded parallel requests: 100/100 in 1.189462884 fmt.Println(benchmarkBoundedParallelRequests(urls, 50)) // Output: 50 bounded parallel requests: 100/100 in 1.17430002 fmt.Println(benchmarkBoundedParallelRequests(urls, 75)) // Output: 75 bounded parallel requests: 100/100 in 1.001383863 fmt.Println(benchmarkBoundedParallelRequests(urls, 100)) // Output: 100 bounded parallel requests: 100/100 in 1.3769354 } -
Montana Flynn revised this gist
Dec 23, 2016 . 1 changed file with 15 additions and 17 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,16 +7,6 @@ import ( "time" ) // a struct to hold the result from each request including an index // which can be used for sorting the results after they come in type result struct { @@ -89,7 +79,8 @@ func boundedParallelGet(urls []string, concurrencyLimit int) []result { return results } // send a bunch of requests and time how long they take func benchmarkBoundedParallelRequests(urls []string, concurrency int) string { boundedParallelTimeStart := time.Now() results := boundedParallelGet(urls, concurrency) seconds := time.Since(boundedParallelTimeStart).Seconds() @@ -98,21 +89,28 @@ func benchmarkBoundedParallelRequests(concurrency int) string { } func main() { // let's make a slice of URLs to send requets to var urls []string for i := 0; i < 100; i++ { urls = append(urls, "http://httpbin.org/get") } fmt.Println(benchmarkBoundedParallelRequests(5)) // Output: 5 bounded parallel requests: 100/100 in 5.533223255 fmt.Println(benchmarkBoundedParallelRequests(10)) // Output: 10 bounded parallel requests: 100/100 in 2.5115351219999997 fmt.Println(benchmarkBoundedParallelRequests(25)) // Output: 25 bounded parallel requests: 100/100 in 1.189462884 fmt.Println(benchmarkBoundedParallelRequests(50)) // Output: 50 bounded parallel requests: 100/100 in 1.17430002 fmt.Println(benchmarkBoundedParallelRequests(75)) // Output: 75 bounded parallel requests: 100/100 in 1.001383863 fmt.Println(benchmarkBoundedParallelRequests(100)) // Output: 100 bounded parallel requests: 100/100 in 1.3769354 } -
Montana Flynn revised this gist
Dec 23, 2016 . 1 changed file with 52 additions and 19 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,63 +3,96 @@ package main import ( "fmt" "net/http" "sort" "time" ) // a slice for the urls we're going to fake var urls []string // make one hundred httpbin and put them in the slice func init() { for i := 0; i < 100; i++ { urls = append(urls, "http://httpbin.org/get") } } // a struct to hold the result from each request including an index // which can be used for sorting the results after they come in type result struct { index int res http.Response err error } // boundedParallelGet sends requests in parallel but only up to a certain // limit, and furthermore it's only parallel up to the amount of CPUs but // is always concurrent up to the concurrency limit func boundedParallelGet(urls []string, concurrencyLimit int) []result { // this buffered channel will block at the concurrency limit semaphoreChan := make(chan struct{}, concurrencyLimit) // this channel will not block and collect the http request results resultChan := make(chan *result) // keen an index and loop through every url we will send a request to for i, url := range urls { // start a go routine with the index and url in a closure go func(i int, url string) { // this sends an empty struct into the semaphoreChan which // is basically saying add one to the limit, but when the // limit has been reached block until there is room semaphoreChan <- struct{}{} // send the request and put the response in a result struct // along with the index so we can sort them later along with // any error that might have occoured res, err := http.Get(url) result := &result{i, *res, err} // now send the result struct through the resultChan so we // can get the results without being able to return them resultChan <- result // once we're done it's we read from the semaphoreChan which // has the effect of removing one from the limit and allowing // another goroutine to start <-semaphoreChan }(i, url) } // make a slice to hold the results we're expecting var results []result // start listening for any results over the resultChan for { // once we've got a result append it to the result slice result := <-resultChan results = append(results, *result) // if we've reached the expected amount of urls then stop if len(results) == len(urls) { break } } // let's sort these results real quick sort.Slice(results, func(i, j int) bool { return results[i].index < results[j].index }) return results } func benchmarkBoundedParallelRequests(concurrency int) string { boundedParallelTimeStart := time.Now() results := boundedParallelGet(urls, concurrency) seconds := time.Since(boundedParallelTimeStart).Seconds() tmplate := "%d bounded parallel requests: %d/%d in %v" return fmt.Sprintf(tmplate, concurrency, len(results), len(urls), seconds) } -
Montana Flynn revised this gist
Dec 21, 2016 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -37,8 +37,8 @@ func boundedParallelGet(urls []string, concurrencyLimit int) []result { result := &result{i, *res, err} resultChan <- result <-semaphoreChan }(i, url) } -
Montana Flynn revised this gist
Dec 16, 2016 . No changes.There are no files selected for viewing
-
Montana Flynn created this gist
Dec 16, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,85 @@ package main import ( "fmt" "net/http" "time" ) var urls []string func init() { for i := 0; i < 100; i++ { urls = append(urls, "http://httpbin.org/get") } } type result struct { i int res http.Response err error } type semaphore struct{} func boundedParallelGet(urls []string, concurrencyLimit int) []result { semaphoreChan := make(chan semaphore, concurrencyLimit) resultChan := make(chan *result) client := http.Client{} for i, url := range urls { go func(i int, url string) { semaphoreChan <- semaphore{} res, err := client.Get(url) defer res.Body.Close() result := &result{i, *res, err} resultChan <- result <-semaphoreChan }(i, url) } var results []result for { select { case result := <-resultChan: results = append(results, *result) if len(results) == len(urls) { return results } } } return results } func benchmarkBoundedParallelRequests(concurrency int) string { boundedParallelTimeStart := time.Now() results := boundedParallelGet(urls, concurrency) seconds := time.Now().Sub(boundedParallelTimeStart).Seconds() tmplate := "%d bounded parallel requests: %d/%d in %v" return fmt.Sprintf(tmplate, concurrency, len(results), len(urls), seconds) } func main() { fmt.Println(benchmarkBoundedParallelRequests(5)) // 5 bounded parallel requests: 100/100 in 5.533223255 fmt.Println(benchmarkBoundedParallelRequests(10)) // 10 bounded parallel requests: 100/100 in 2.5115351219999997 fmt.Println(benchmarkBoundedParallelRequests(25)) // 25 bounded parallel requests: 100/100 in 1.189462884 fmt.Println(benchmarkBoundedParallelRequests(50)) // 50 bounded parallel requests: 100/100 in 1.17430002 fmt.Println(benchmarkBoundedParallelRequests(75)) // 75 bounded parallel requests: 100/100 in 1.001383863 fmt.Println(benchmarkBoundedParallelRequests(100)) // 100 bounded parallel requests: 100/100 in 1.3769354 }