ããã¯Sau Sean Changã®ããã°æçš¿ã®ç¿»èš³ã§ãã ååã§ã¯Goã§ãã©ãã¢ã¶ã€ã¯ãäœæããæ¹æ³ã説æããåŸåã§ã¯ç«¶äºåïŒãã£ãã«ããŽã«ãŒãã³ïŒãè¿œå ããŠããã°ã©ã ã®å®è¡ãå éããŸãã
翻蚳ã®äžæ£ç¢ºãã«ã€ããŠã¯ãå人ã§æžããŠãã ãããæ°ã¶æåãç§ã®èŠªåã§ãã
ãµãã£ã·ã¥ã»ã¿ãªã ã¯çŽ æŽãããã¢ã€ãã¢ãææ¡ããŸãã-Goããã°ã©ããŒã®ã¹ãã«ãé«ããããã«ãGoã§ããã€ãã®ã³ã³ããäœæããããšã§ãã ãã®ãããžã§ã¯ãã®ã¢ã€ãã¢ã¯ãæ¯æïŒãŸãã¯ãããããïŒããã°ã©ãã³ã°ã¿ã¹ã¯ãèãåºãããšã§ããããã¯ãGoã³ãã¥ããã£ã«ãšã£ãŠæ°é®®ã§èå³æ·±ã課é¡ã§ãã åè³è
ã¯è³åãåãåããŸãããããã«éèŠãªããšã¯ãããã¯äºãã«ããããŠç¹ã«èªåèªèº«ãå©ããè©Šã¿ã§ãã ãµãã£ã·ã¥ã¯ç§ã«ã¿ã¹ã¯ãèãåºãããã«é Œã¿ãŸããããããŠãç§ã¯åãã§
3çªç®ã®ç«¶äºã®ããã«ãããæãã€ããŸããïŒãã£ã¬ã³ãžïŒ3ïŒã
ç§ã®ã»ãšãã©ã®ãã£ãªã¢ã§Webã¢ããªã±ãŒã·ã§ã³ããã°ã©ããŒã§ãã£ããããèªç¶ãªèãã¯Webã¢ããªã±ãŒã·ã§ã³ã®ç«¶äºãèãåºãããšã§ããã ãããŠæè¿ãããã«ãœã³ã§
ã¢ã¶ã€ã¯ãçæããRubyã¹ã¯ãªãããæžããã®ã§ã
ã¢ã¶ã€ã¯ãçæããWebã¢ããªã±ãŒã·ã§ã³ãäœæããã¿ã¹ã¯ã§ãããã®ã¢ã€ãã¢ãçµã¿åãããããšãèããŸããã

æ£çŽãªãšãããã¿ã¹ã¯ã®å
¬éæç¹ã§ã¯ãç§ã®Webã¢ããªã±ãŒã·ã§ã³ã¯ãŸã äœæãããŠããŸããã ã³ã³ãã¹ããçµãã£ãŠããæžãå§ããŸããã ã¢ã¶ã€ã¯ã®Webã¢ããªã±ãŒã·ã§ã³ãäœæããã®ã«çŽ2æ¥ããããŸããã ããããããã°ã©ã ãé«éåããããã«Goã«ããã«ç«¶äºåãè¿œå ãããã£ããããçµäºããŸããã§ããã ãã®ããã°æçš¿ã¯ç§ããã£ãããšã®çµæã§ãã
ãã®ãšã³ããªã®ãã¹ãŠã®ã³ãŒãã¯
github.com/sausheong/mosaicã«ãããŸãã githubã®ã³ãŒãã¯ã以äžã«ç€ºããã®ãšãããã«ç°ãªãããšã«æ³šæããŠãã ããã
ãã¢ã¯ã
mosaic.saush.comã§è¡šç€ºã§ããŸãã
ïŒã¬ãŒã³ã«æ³šæããŠãã ãã-倧ããªç»åã§ã¢ããªã±ãŒã·ã§ã³ãæããããªãã§ãã ããããµãŒããŒã¯åŒ±ãã®ã§ã4 MBã®ç»åã§ãåãã§ã¯ã©ãã·ã¥ããŸãïŒã Tutumçµç±ã§Dockerã䜿çšããŠDigital Oceanã§ãã¹ããããŸãã ãµãŒããŒã§ã®ãã¢ã®ããã©ãŒãã³ã¹ã¯ããã®èšäºã»ã©é«ãã¯ãããŸãããããã¯ã1ã€ã®CPU VMãš512 MBãã䜿çšããªãããã§ãã
åçã¢ã¶ã€ã¯ãäœæããŸãã
åçã¢ã¶ã€ã¯ãŸãã¯ãã©ãã¢ã¶ã€ã¯ã¯ãé·æ¹åœ¢ã®ã»ã¯ã·ã§ã³ïŒéåžžã¯åããµã€ãºïŒã«åå²ãããåçïŒéåžžã¯åçïŒã§ããããããããæ°ããåçã«çœ®ãæããããŸãã é ãããããŸãã¯ç®ã现ããŠèŠããšãå
ã®åçãèŠãããšãã§ããŸãã ããèŠããšã倧ããªç»åã¯å®éã«ã¯æ°çŸãŸãã¯æ°åãã®å°ããªã¿ã€ã«ç»åã§æ§æãããŠããããšãããããŸãã
åºæ¬çãªèãæ¹ã¯ç°¡åã§ã-Webã¢ããªã±ãŒã·ã§ã³ã䜿çšãããšããŠãŒã¶ãŒã¯å¿
èŠãªç»åãããŠã³ããŒãã§ããããã«åºã¥ããŠã¢ã¶ã€ã¯ãçæãããŸãã ç°¡åã«ããããã«ãåçã¯ãã£ã¬ã¯ããªã«ããªããŒããããé©åãªãµã€ãºã§ãããšæ³å®ããŸããã
ãã©ãã¢ã¶ã€ã¯ã®ã¢ã«ãŽãªãºã ããå§ããŸãããã Webã¢ããªã±ãŒã·ã§ã³ã¯ç°¡åãªæé ã§æ§æãããŠããããµãŒãããŒãã£ã®ã©ã€ãã©ãªã䜿çšããã«äœæã§ããŸãã
- ç»åã®ããŒã¿ããŒã¹ãã¿ã€ã«ã®ããã·ã¥ããã£ã¬ã¯ããªãåçã§ã¹ãã£ã³ããŠäœæããŸãã 次ã«ããã¡ã€ã«åãããŒã§ãããç»åã®å¹³åè²ãå€ã§ãããã£ã¹ãã¬ã€ãäœæããŸãã åãã¯ã»ã«ã®èµ€ãç·ãéïŒRGBïŒã®3ã€ã®èŠçŽ ã®ã¿ãã«ã«ã€ããŠå¹³åè²å€ãèšç®ããããã¹ãŠã®èµ€ãç·ãéã®ãã¯ã»ã«ã®å€ãåèšãã¯ã»ã«æ°ã§é€ç®ãããŠå ç®ãããŸãã ïŒã¬ãŒã³ã«æ³šæããŠãã ãã-èè
ã¯ã¿ãã«ãšããçšèªã䜿çšããŸãããGoã«ã¯ã¿ãã«ã¯ãããŸãããé
åã®ããããã£ã¯éåžžã«äŒŒãŠããŸããã¹ã©ã€ã¹ãšæ··åããªãã§ãã ããïŒã
- ã¿ãŒã²ããç»åãé©åãªãµã€ãºã®å°ããªã¿ã€ã«ã«åãåããŸãã
- ã¿ãŒã²ããç»åã®åã»ã¯ã·ã§ã³ã«ã€ããŠãå·Šäžã®ãã¯ã»ã«ã®å¹³åè²ãèšç®ãããããã»ã¯ã·ã§ã³å
šäœã®å¹³åè²ã§ãããšä»®å®ããŸãã
- ã¿ãŒã²ããã€ã¡ãŒãžã®å¯Ÿå¿ããã»ã¯ã·ã§ã³ã®å¹³åè²ã«æãããäžèŽããã¿ã€ã«ã®ããŒã¿ããŒã¹ããé©åãªã¿ã€ã«ãæ¢ãããã©ããã¹ã¯ã®é©åãªå Žæã«é
眮ããŸãã æé©ãªäžèŽãèŠã€ããã«ã¯ãã¿ãã«ã®åè²[3]ã3次å
空éã®ãã€ã³ãã«å€æããããšã«ããã[3]ã¿ãã«ã®2è²éã®ãŠãŒã¯ãªããè·é¢ãèšç®ããŸãã
- èŠã€ãã£ãã¿ã€ã«ãããŒã¿ããŒã¹ããåé€ããŠãæ®ãã®ã¿ã€ã«ãäžæã«ãªãããã«ããŸãã
ã¢ã¶ã€ã¯ãäœæããããã«æžããããã¹ãŠã®ã³ãŒããåäžã®mosaic.goãã¡ã€ã«ã«é
眮ããŸããã ãã®ãã¡ã€ã«ããåæ©èœãç解ããŸãããã
ãŸããé¢æ°ã®
colorColorããå§ããŸãããã®é¢æ°ã¯ãç»åã®ãã¹ãŠã®èµ€ãç·ãéã®ãã¯ã»ã«ã®å€ãèšç®ããããããåèšããŠïŒåå¥ã«ïŒãå€ã®åââåèšãç»åã®ãã¯ã»ã«ã®ç·æ°ã§é€ç®ããŸãã 次ã«ããããã®å€ã§æ§æããã[3]ã¿ãã«ïŒå®éã«ã¯3ã€ã®èŠçŽ ã®é
åïŒãè¿ããŸãã
次ã«ã
ãµã€ãºå€æŽæ©èœãèŠãŠãã ãã
tilesDBé¢æ°ã¯ãç»åãã£ã¬ã¯ããªãã¹ãã£ã³ããŠç»åã®ããŒã¿ããŒã¹ãäœæããŸãã
ã¿ã€ã«ããŒã¿ããŒã¹ã¯ãããŒã«æååãã[3]å€ã«ã¿ãã«ïŒãã®å Žåã¯3ã€ã®èŠçŽ ã®é
åïŒãå«ããããã³ã°ã§ãã ãã£ã¬ã¯ããªå
ã®åç»åãã¡ã€ã«ãéããç»åã®å¹³åè²ãèšç®ããŠè¡šç€ºå€ãèšå®ããŸãã ã¿ã€ã«ããŒã¿ããŒã¹ã¯ãç»åãã£ã¬ã¯ããªã§é©åãªã¿ã€ã«ãæ€çŽ¢ããããã«äœ¿çšãããŸãã ã¿ãã«ã®ã¿ãŒã²ããã«ã©ãŒå€[3]ãšãšãã«ãæãè¿ãé¢æ°ã«æž¡ãããŸãã
ããŒã¿ããŒã¹å
ã®åå€ãã¿ãŒã²ããã«ã©ãŒãšæ¯èŒãããæå°ã®å·®ãæã€å€ãæé©ãªã¿ã€ã«ãšããŠè¿ãããŸãã èŠã€ãã£ãå€ã¯ããŒã¿ããŒã¹ããåé€ãããŸãã
è·é¢é¢æ°ã¯ã2ã€ã®[3]ã¿ãã«éã®ãŠãŒã¯ãªããè·é¢ãèšç®ããŸãã
æåŸã«ãåãã©ãã¢ã¶ã€ã¯ã®äœææã«ã¿ã€ã«ããŒã¿ããŒã¹ãã¹ãã£ã³ããŠããŒããããšãèŠèŠãããªããŸãã ãããäžåºŠã ãè¡ãããã©ãã¢ã¶ã€ã¯ãäœæãããšãã«ãã®ããŒã¿ããŒã¹ã®ã¯ããŒã³ãäœæããŸãã ãœãŒã¹
TILESDBã¿ã€ã«
ããŒã¿ããŒã¹ã¯ãã°ããŒãã«å€æ°ãšããŠäœæãããWebã¢ããªã±ãŒã·ã§ã³ã®éå§æã«å®£èšãããŸãã
var TILESDB map[string][3]float64
ãã©ãã¢ã¶ã€ã¯Webã¢ããªã±ãŒã·ã§ã³
ãã©ãã¢ã¶ã€ã¯ãçæããããã®é¢æ°ãæºåããããWebã¢ããªã±ãŒã·ã§ã³ã®äœæãéå§ã§ããŸãã Webã¢ããªã±ãŒã·ã§ã³ã¯ã
main.goãšããååã®ãœãŒã¹ãã¡ã€ã«ã«é
眮ãããŸã
ã package main import ( "fmt" "html/template" "net/http" "bytes" "encoding/base64" "image" "image/draw" "image/jpeg" "os" "strconv" ) func main() { mux := http.NewServeMux() files := http.FileServer(http.Dir("public")) mux.Handle("/static/", http.StripPrefix("/static/", files)) mux.HandleFunc("/", upload) mux.HandleFunc("/mosaic ", mosaic) server := &http.Server{ Addr: "127.0.0.1:8080", Handler: mux, }
ãã©ãã¢ã¶ã€ã¯ãäœæããããã®åºæ¬çãªããžãã¯ã¯ããã³ãã©ãŒã§ãã
ã¢ã¶ã€ã¯é¢æ°ã§èª¬æãããŠ
ããŸãã æåã«ãããŠã³ããŒããããã¡ã€ã«ãšãã©ãŒã ã®ã¿ã€ã«ã®ãµã€ãºãååŸããŸãã
次ã«ãããŠã³ããŒãããã¿ãŒã²ããã€ã¡ãŒãžããã³ãŒããããã©ãã¢ã¶ã€ã¯çšã®æ°ããã€ã¡ãŒãžãäœæããŸãã
ãŸãããœãŒã¹ã¿ã€ã«ããŒã¿ããŒã¹ã®ã¯ããŒã³ãäœæããåã¿ã€ã«ã®ãœãŒã¹ãã€ã³ãã決å®ããŸãïŒåŸã§
ã€ã¡ãŒãž/æç»ããã±ãŒãžã«å¿
èŠïŒ
ããã§ãã¿ãŒã²ããã€ã¡ãŒãžå
ã®éžæãããµã€ãºã®ãã¹ãŠã®ã¿ã€ã«ãå埩åŠçããæºåãã§ããŸããã
for y := bounds.Min.Y; y < bounds.Max.Y; y = y + tileSize { for x := bounds.Min.X; x < bounds.Max.X; x = x + tileSize {
ã»ã¯ã·ã§ã³ããšã«ãå·Šäžã®ãã¯ã»ã«ãéžæãããããã»ã¯ã·ã§ã³ã®å¹³åè²ã§ããããšã決å®ããŸãã 次ã«ãããŒã¿ããŒã¹å
ã§æãé©ããè²ã®ã¿ã€ã«ãæ¢ããŸãã ã¿ã€ã«åãããããŒã¿ããŒã¹ã¯ãã¡ã€ã«ã®ååãäžãããã®ãµã€ãºã¯æå®ããããã®ã«å€æŽããŸãã çµæã®ã¿ã€ã«ã¯ã以åã«äœæãããã¢ã¶ã€ã¯ïŒnewimageïŒã«é
眮ãããŸãã
ãã©ãã¢ã¶ã€ã¯ãäœæãããããJPEG圢åŒã§ãšã³ã³ãŒãããŠãããbase64æååã«ãšã³ã³ãŒãããŸãã
buf1 := new(bytes.Buffer) jpeg.Encode(buf1, original, nil) originalStr := base64.StdEncoding.EncodeToString(buf1.Bytes()) buf2 := new(bytes.Buffer) jpeg.Encode(buf2, newimage, nil) mosaic := base64.StdEncoding.EncodeToString(buf2.Bytes()) t1 := time.Now() images := map[string]string{ "original": originalStr, "mosaic": mosaic, "duration": fmt.Sprintf("%v ", t1.Sub(t0)), } t, _ := template.ParseFiles("results.html") t.Execute(w, images)
å
ã®ã¿ãŒã²ããç»åãšãã©ãã¢ã¶ã€ã¯ã¯ã次ã®ããŒãžã«è¡šç€ºããããã«
results.htmlãã³ãã¬ãŒãã«éä¿¡ãããŸãã ã芧ã®ãšãããç»åã¯base64 WebããŒãžã®ã³ã³ãã³ãã«çŽæ¥åã蟌ãŸããããŒã¿URLã«è¡šç€ºãããŸãã
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Mosaic</title> ... </head> <body> <div class='container'> <div class="col-md-6"> <img src="data:image/jpg;base64,{{ .original }}" width="100%"> <div class="lead">Original</div> </div> <div class="col-md-6"> <img src="data:image/jpg;base64,{{ .mosaic }}" width="100%"> <div class="lead">Mosaic â {{ .duration }} </div> </div> <div class="col-md-12 center"> <a class="btn btn-lg btn-info" href="/">Go Back</a> </div> </div> <br> </body> </html>
äœæãããã¢ã¶ã€ã¯ã®ã¹ã¯ãªãŒã³ã·ã§ããïŒ
åºæ¬çãªãã©ãã¢ã¶ã€ã¯ãã©ãã¢ã¶ã€ã¯ãçæããããã®åºæ¬çãªWebã¢ããªã±ãŒã·ã§ã³ãã§ããã®ã§ã軜éã¹ã¬ãããšé¢æ°ã®åæå®è¡ãåããããŒãžã§ã³ãè¿œå ããŸãããã
競äºåã®ããWebã¢ããªã±ãŒã·ã§ã³ã¢ã¶ã€ã¯
競äºåã䜿çšããéã®æãäžè¬çãªã¿ã¹ã¯ã®1ã€ã¯ãçç£æ§ã®åäžã§ãã ç§ãæžããWebã¢ããªã±ãŒã·ã§ã³ã¯ã2.25ç§ã§151 KBã®JPEGã€ã¡ãŒãžããåçã¢ã¶ã€ã¯ãäœæããŸãã é床ã¯ç®èŠãããã®ã§ã¯ãªãã軜éã¹ããªãŒã ãè¿œå ããããšã§ç¢ºãã«æ¹åã§ããŸãã ãã®äŸã§ã¯ãããªãåçŽãªãŽã«ãŒãã³ã®åæå®è¡ã¢ã«ãŽãªãºã ã䜿çšããŸãã
- å
ã®ç»åã4ã€ã®éšåã«åå²ãã
- åæã«åŠçããŸã
- çµæã1ã€ã®ã¢ã¶ã€ã¯ã«æ»ã
ããã¯æ¬¡ã®ããã«è¡šãããšãã§ããŸãã
競åã¢ã«ãŽãªãºã ããã¯ã軜éã¹ã¬ããã䜿çšããŠããã©ãŒãã³ã¹ãåäžãããå¯äžã®æ¹æ³ã§ã¯ãªããåçŽã§çŽæ¥çãªæ¹æ³ã§ããããšã«æ³šæããŠãã ããã
å€æŽããå¯äžã®é¢æ°ã¯
ã¢ã¶ã€ã¯ãã³ãã©ãŒã§ãã 以åã¯ããã©ãã¢ã¶ã€ã¯ãäœæããããã®å¯äžã®ãã³ãã©ããããŸããã ãã©ãã¢ã¶ã€ã¯Webã¢ããªã±ãŒã·ã§ã³ã®ç«¶äºåã®ããããŒãžã§ã³ã§ã¯
ãåçã
ã«ããããŠ
çµåãã2ã€ã®æ°ããæ©èœã«åå²ããå¿
èŠããããŸãã
ã¢ã¶ã€ã¯é¢æ°ãã
ã«ãããš
çµåã®äž¡æ¹ãåŒã³åºããŸãã
func mosaic(w http.ResponseWriter, r *http.Request) { t0 := time.Now() r.ParseMultipartForm(10485760)
ã«ããç»åã¯ã
ã«ããæ©èœã«ãã£ãŠåŠçã
ããŸãã
ã¿ãŒã²ããç»åã4ã€ã®éšåã«åå²ããå
ã®ç»åã¯ãåæã«åŠçããããã«4ã€ã®è±¡éã«åå²ãããŸãã
c1 := cut(original, &db, tileSize, bounds.Min.X, bounds.Min.Y, bounds.Max.X/2, bounds.Max.Y/2) c2 := cut(original, &db, tileSize, bounds.Max.X/2, bounds.Min.Y, bounds.Max.X, bounds.Max.Y/2) c3 := cut(original, &db, tileSize, bounds.Min.X, bounds.Max.Y/2, bounds.Max.X/2, bounds.Max.Y) c4 := cut(original, &db, tileSize, bounds.Max.X/2, bounds.Max.Y/2, bounds.Max.X, bounds.Max.Y)
ãããã¯ãŽã«ãŒãã³ã®ãªãéåžžã®æ©èœã§ããããšã«æ°ã¥ããã§ããããã©ã®ããã«åæã«å®è¡ã§ããŸããïŒ äºå®ãããèªäœã®äžã®
cuté¢æ°ã¯å¿åã®ãŽã«ãŒãã³ãäœæãããã£ã³ãã«ãè¿ããŸãã
func cut(original image.Image, db *map[string][3]float64, tileSize, x1, y1, x2, y2 int) <-chan image.Image { c := make(chan image.Image) sp := image.Point{0, 0} go func() { newimage := image.NewNRGBA(image.Rect(x1, y1, x2, y2)) for y := y1; y < y2; y = y + tileSize { for x := x1; x < x2; x = x + tileSize { r, g, b, _ := original.At(x, y).RGBA() color := [3]float64{float64(r), float64(g), float64(b)} nearest := nearest(color, db) file, err := os.Open(nearest) if err == nil { img, _, err := image.Decode(file) if err == nil { t := resize(img, tileSize) tile := t.SubImage(t.Bounds()) tileBounds := image.Rect(x, y, x+tileSize, y+tileSize) draw.Draw(newimage, tileBounds, tile, sp, draw.Src) } else { fmt.Println("error:", err) } } else { fmt.Println("error:", nearest) } file.Close() } } c <- newimage.SubImage(newimage.Rect) }() return c }
ããžãã¯ã¯ãå
ã®Webã¢ããªã±ãŒã·ã§ã³ãšãŸã£ããåãã§ãã
cuté¢æ°ã§ãã£ãã«ãäœæããèšç®çµæããã®ãã£ãã«ã«éä¿¡ããå¿åãŽã«ãŒãã³ã宣èšããŸãã ãã®åŸããã®ãã£ã³ãã«ãè¿ããŸãã ãããã£ãŠããã£ãã«ã¯ããã«
ã¢ã¶ã€ã¯ãã³ãã©ãŒé¢æ°ã«è¿ããããã©ãã¢ã¶ã€ã¯ã®ã»ã°ã¡ã³ãã¯ãå®å
šã«åŠçããããšããã«ãã®ãã£ãã«ã«éä¿¡ãããŸãã
å
ã®ç»åã4ã€ã®éšåã«åå²ããããããåå¥ã«ãã©ãã¢ã¶ã€ã¯ã«å€æããŸããã äœåãçµã¿ç«ãŠãŠ1ã€ã®åçã«æ»ããšããããŸããã
func combine(r image.Rectangle, c1, c2, c3, c4 <-chan image.Image) <-chan string { c := make(chan string)
ã«ããæ©èœãšåæ§ã«ãç»åæ¥ç¶ã®ã¡ã€ã³ããžãã¯ã¯ãŽã«ãŒãã³ã«ããããã£ãã«ã¯ããŒã¿ãåä¿¡ããããã ãã«äœæãããŸãã
å¿åãŽã«ãŒãã³ã§ã¯ã
ã³ããŒå€æ°ãå²ãåœãŠãããå¥ã®å¿åé¢æ°ãäœæãããŸãã ãã®é¢æ°ã¯ããã©ãã¢ã¶ã€ã¯ã®ã»ã°ã¡ã³ããæçµçãªã¢ã¶ã€ã¯ã«ã³ããŒããŸãã åŸã§å¥ã®ãŽã«ãŒãã³ãšããŠèµ·åãããããããã€å®è¡ãããããç¥ãããšã¯ã§ããŸããã ãã®åé¡ã解決ããã³ããŒæ©èœã®å®è¡ãåæããã«ã¯ã
WaitGroupã䜿çšã
ãŸã ã
WaitGroupã¿ã€ãã®
wgå€æ°ãäœæãã
Addã¡ãœããã䜿çšããŠãã«ãŠã³ã¿ãŒã4ã«èšå®ããŸãã
ã³ããŒé¢æ°ãå®è¡ããããã³ã«ã
Doneã¡ãœãããåŒã³åºãããã«ãŠã³ã¿ãŒã1æžå°ããŸã
ãWaitã¡ãœããã¯ãç»åã®ãšã³ã³ãŒãåã«å³å¯ã«åŒã³åºãããã¢ã¶ã€ã¯ã®4ã€ã®éšåãã¹ãŠã®çæãä¿èšŒããŸãå
šäœåãååŸããŸãã
çµåé¢æ°ã¯ãã¢ã¶ã€ã¯ã®ã»ã°ã¡ã³ããå«ã
ã«ããé¢æ°ãã4ã€ã®ãã£ãã«ãåãå
¥ããããšãæãåºããŠãã ããã å®éãã»ã°ã¡ã³ãããã£ãã«ã«ãã€è¡šç€ºããããã¯æ確ã§ã¯ãããŸããã ãããã®ã»ã°ã¡ã³ããé çªã«ååŸããããšããããšãã§ããŸãããããã¯ç«¶äºçãªã¢ãããŒãã®ããã«ã¯èŠããŸããã ãã ããselectã¹ããŒãã¡ã³ãã䜿çšããŠã»ã°ã¡ã³ããåä¿¡ãããããã«åŠçãéå§ããããšæããŸãã
var s1, s2, s3, s4 image.Image var ok1, ok2, ok3, ok4 bool for { select { case s1, ok1 = <-c1: go copy(img, s1.Bounds(), s1, image.Point{r.Min.X, r.Min.Y}) case s2, ok2 = <-c2: go copy(img, s2.Bounds(), s2, image.Point{r.Max.X / 2, r.Min.Y}) case s3, ok3 = <-c3: go copy(img, s3.Bounds(), s3, image.Point{r.Min.X, r.Max.Y / 2}) case s4, ok4 = <-c4: go copy(img, s4.Bounds(), s4, image.Point{r.Max.X / 2, r.Max.Y / 2}) } if (ok1 && ok2 && ok3 && ok4) { break } }
ããã¯ç¡éã«ãŒãã§ãããåå埩ã§æ¢è£œã®ããŒã¿ãå«ãã±ãŒã¹ãéžæããããšããŸãïŒããŒã¿ãåæã«è€æ°ã®ãã£ãã«ã«ããå ŽåãGoã¯èª€ã£ãŠ1ã€ã®ã±ãŒã¹ãéžæããŠå®è¡ããŸãïŒã ãã£ã³ãã«ã®image.Imageãåãåã£ããã
ã³ããŒæ©èœã®ãŽã«ãŒãã³ãå®è¡ããŸãã ãã£ã³ãã«ã«ã¯ããã€ãã®å€ãããããšã«æ³šæããŠãã ããã 2çªç®ã®å€ïŒok1ãok2ãok3ããŸãã¯ok4ïŒã¯ããã£ãã«ããããŒã¿ãåä¿¡ãããšããäºå®ã瀺ããŠããŸãã 4ã€ã®ãã£ãã«ãã¹ãŠããããŒã¿ãåä¿¡ãããšãç¡éãµã€ã¯ã«ãäžæãããŸãã
次ã«ã以åã«äœ¿çšãããWaitGroupã¿ã€ããèŠããŠãããŠãã ããã
çµåæ©èœã¯ããã©ãã¢ã¶ã€ã¯ã®çµæã®éšåãå¥ã
ã®ãŽã«ãŒãã³ã«çµåããŸããããããã¯åæã«çµäºããªãå ŽåããããŸãã ãããã£ãŠãWaitGroupã¿ã€ãã®Waitã¡ãœããã¯ããã¹ãŠã®éšåãäžç·ã«çµã¿ç«ãŠããããŸã§ãã€ã¡ãŒãžã®ãšã³ã³ãŒãããããã¯ããŸãã
åãç»åãšã¢ã¶ã€ã¯çæã®çµæã®ã¹ã¯ãªãŒã³ã·ã§ããïŒ
競äºåã®ããWebã¢ããªã±ãŒã·ã§ã³ã¢ã¶ã€ã¯éãç®ã¯ãçæããããã©ãã¢ã¶ã€ã¯ã®éãã«æ°ä»ãããšãã§ããŸãã æçµçãªã¢ã¶ã€ã¯ã¯4ã€ã®éšåããæ§æãããã¢ã«ãŽãªãºã ã¯ç²ããšããžãåãããŸããã ãã ããããã©ãŒãã³ã¹ã®éãã¯æããã§ããããŒã¹ã¢ããªã±ãŒã·ã§ã³ã¯2.25ç§ã§ã¢ã¶ã€ã¯ãçæãã競åå®è£
ã¯646ããªç§ã§4åéãåãããšãè¡ããŸãã
泚ææ·±ãèªè
ã¯ãäž¡æ¹ã®Webã¢ããªã±ãŒã·ã§ã³ã1ã€ã®ããã»ããµã³ã¢ã§ã®ã¿å®è¡ãããããšã«æ°ä»ãã§ãããã Rob Pikeã圌ã®èšäºã
競äºåã¯äžŠåæ§ã§
ã¯ãªã ãã§æžããŠããããã«ãããã¯åçŽãªã¢ã«ãŽãªãºã ãæ¡çšãã䞊ååŒã³åºããªãã§è»œéã¹ã¬ããã«åå²ããæ¹æ³ã§ãã ç¬ç«ããŠå®è¡ããããšããäºå®ã«ããããããããŽã«ãŒãã³ã¯ã©ãã䞊è¡ããŠå®è¡ãããŸããïŒçµå±ã䜿çšãããCPUã¯1ã€ã ãã§ãïŒã
ãã¡ãããæåŸã®ã¹ããããèžãŸãªãããšã¯æ®é
·ã§ããããã¯ãããããã¹ãŠãããã»ããµãŒã®ããã€ãã®ã³ã¢ã§å®è¡ããæ¹æ³ã瀺ããŸãã ãããè¡ãã«ã¯ã
å®è¡æã«GOMAXPROCSãããã»ããµã®ã³ã¢ã®æ°ã«èšå®ããã ãã§ãã
main.goãã¡ã€ã«ã«å€æŽãå
¥åããå¿
èŠããããŸãã å€æŽãå ããåã«ã
ã©ã³ã¿ã€ã ããã±ãŒãžãã€ã³ããŒãããããšãå¿ããªãã§ãã ããã
ïŒæ³šã¬ãŒã³-ããŒãžã§ã³Go 1.5以éã§ã¯é¢ä¿ãããŸãããäºå®ãGOMAXPROCSã®ããã©ã«ãå€ã¯æ倧1.5ã§ãããèè
ãèšãããã«ã1.5ãããããã©ã«ãã®GOMAXPROCSã¯ã³ã¢ã®æ°ã«çãããªããŸãïŒ func main() {
ç«ã®åçãå床ã³ã³ãã€ã«ããŠã¢ããããŒãããŸããã
8 CPUã§å®è¡ããã競äºåã®ããWebã¢ããªã±ãŒã·ã§ã³ã¢ã¶ã€ã¯ã芧ã®ãšãããé床ã¯646ããªç§ãã216ããªç§ã«3åã«å¢å ããŠããŸãïŒ ãã®æéã2.25ç§ã§ã¢ã¶ã€ã¯ãçæãããªãªãžãã«ã®Webã¢ããªã±ãŒã·ã§ã³ãšæ¯èŒãããšãçç£æ§ã¯10åã«ãªããŸããïŒ ããã¯å®éã®æ¯èŒã§ãã æåã®ã¢ããªã±ãŒã·ã§ã³ã¯8ã³ã¢ã§å®è¡ããŸããã§ããããå®è¡ããŠãã競åã䜿çšããªãã£ããããããã©ãŒãã³ã¹ã®åäžã¯èŠãããŸããã
ãŸãããã©ãã¢ã¶ã€ã¯çæã¢ã«ãŽãªãºã ã®ã·ã³ã°ã«ã¹ã¬ããããã³ç«¶åå®è£
ã«åãã¢ã«ãŽãªãºã ã䜿çšããããšã«æ³šæããããšãèå³æ·±ãã§ãã å®éãmosaic.goãã¡ã€ã«ã«ã¯å€æŽãå ããŠããŸããã å¯äžã®éãã¯åæå®è¡æ§ã§ãããããã¯ãããã©ãã»ã©åŒ·åãã蚌æããŠããŸãã