æçš¿ã¯ãI PRãããã«ãªãããããããžã§ã¯ãã®æ©èœã®æŠèŠãç°¡åã«èª¬æããŸãã ããã¯ã1æ¥ãããçŽ6å件ã®ããããåŠçããé«è² è·ã®Webã¢ããªã±ãŒã·ã§ã³ã§ãïŒããŒã¯è² è·ã¯1ç§ããã1äžãªã¯ãšã¹ããè¶ ããŸãïŒã èŠæ±ã®çŽ80ïŒ ã¯ãã£ãã·ã¥ããéä¿¡ã§ããæ®ãã¯å®å šã«åŠçããå¿ èŠããããŸãã äœæ¥ããŒã¿ã¯äž»ã«PostgreSQLã«åºã¥ããŠãããäžéšã¯ãã©ãããªæ§é ã®ãã€ããªãã¡ã€ã«ïŒã€ãŸããå®éã«ã¯é åã§ãããã¡ã¢ãªã§ã¯ãªããã¡ã€ã«å ïŒã§ãã Perlã¯ã©ã¹ã¿ãŒã¯ãããã©ãŒãã³ã¹ããŒãžã³ãå®éã«äœ¿ãæãããã8å°ã®24å°ã®æ žæ©ã§æ§æãããŠããŸãã.Goã¯ã©ã¹ã¿ãŒã¯ããã§ã«6å°ã«ãªãã3ã€ä»¥äžã®äºåã確èªãããŠããŸãã ããã«ãããã«ããã¯ã¯ããã»ããµãŒãOSããã®ä»ã®ããŒããŠã§ã¢ããœãããŠã§ã¢ã»ã©ã§ã¯ãããŸãããããã¯ãšã³ããœãããŠã§ã¢ãã©ãã»ã©åŒ·åã§ãã£ãŠãã1å°ã®ãã·ã³ã§1ç§éã«10kã®éèŠã§ãªãèŠæ±ãåŠçããããšã¯ç©ççã«ç°¡åã§ã¯ãããŸããã
éçºã¹ããŒã
ãªãã¡ã¯ã¿ãªã³ã°åã®Goã®çµéšã¯æå°éã§ããã 1幎以äžãç§ã¯èšèªãèŠãŠã ä»æ§ãã«ããŒããã«ããŒãŸã§ç 究ããå ¬åŒãŠã§ããµã€ããªã©ã§æçšãªè³æãç 究ããè¢ããŸãã£ãŠä»äºã«åããããæºåãã§ããŠãããšæããŸããã äœæ¥ã®æéã®åæè©äŸ¡ã¯3ã6é±éã§ããã äœæ¥çšããŒã¿çã¯6é±ç®ã®çµããã«éã«åãããã«æºåãã§ããŠããŸããããçµããã«è¿ã¥ããšãããæéããªããšæãå§ããŠããŸããã ãã°ã®ã¯ãªãŒã³ã¢ãããšããã©ãŒãã³ã¹ã®æé©åã«ã¯ããã«1ãæããããŸããã
æåã¯ç¹ã«å°é£ã§ããããæéãçµã€ã«ã€ããŠãä»æ§ã次第ã«èŠãªããŠã¯ãªããªããªããã³ãŒãã¯ãããããã«ãªããŸããã æåã«1æéã§Perlã§ã³ãŒãã£ã³ã°ã§ããæ©èœã䜿çšããçµæ¥Goã«è²»ãããªããã°ãªããªãã£ãå Žåããã®ã®ã£ããã¯å€§å¹ ã«çãŸããŸããã ãããããšã«ãããGoã§ã®ããã°ã©ãã³ã°ã¯Perlã®ããã°ã©ãã³ã°ãããããªãé·ããªããŸããäœæ¥ã«å¿ èŠãªæ§é ãããŒã¿åãã€ã³ã¿ãŒãã§ãŒã¹ãèããã³ãŒãã§ãã¹ãŠèšè¿°ããã¹ã©ã€ã¹ããããããã£ãã«ã®åæåãè¡ããnilã®ãã§ãã¯ãèšè¿°ããªããã°ãªããŸãã...ããã«ããããã¹ãŠãã¯ããã«åçŽã«ãªããŸããæ§é äœã«ããã·ã¥ã䜿çšããå¿ èŠãããã以åã«ãã£ãŒã«ãã宣èšããå¿ èŠããªããããã°ã©ããŒã«ãšã£ãŠããå€ãã®æ§æç³è¡£ããããŸãã å°ãªããšã䞊ã¹æ¿ããæ¯èŒãã-Goã§ã¯ãããŒã¿æ¯èŒã®ããã«ã¯ããŒãžã£ãŒãæå®ããæ¹æ³ã¯ãããŸãããé·ããååŸããããã«åå¥ã®é¢æ°ãç»é²ããå¿ èŠããããŸãããŸããã€ã³ããã¯ã¹æ¯èŒé¢æ°ã«å ããŠãé åå ã®å Žæã§èŠçŽ ã亀æããããã«å¥åã®é¢æ°ãèšè¿°ããå¿ èŠããããŸã ãããŠããªãã§ããïŒ ãžã§ããªãã¯ããªãããããœãŒãé¢æ°ã¯ãäœãå ¥ã蟌ãã ã®ãããã®å€ã®äº€æãã©ã®ããã«ãªãã»ããããã®ããææ¡ããããããç¹å¥ã«å®£èšãããSwapïŒiãjïŒãåŒã³åºãæ¹ãç°¡åã§ãã
䞊ã¹æ¿ãã«å ããŠã/ whileïŒïŒ{...} continue {...}ã®Perlã³ã³ã¹ãã©ã¯ãã®æ¬ åŠã«ãæéãåããŸããïŒçŸåšã®å埩ã次ã®æŒç®åã«ãã£ãŠæ©æã«äžæãããŠãã continueãããã¯ãå®è¡ãããŸãïŒã Goã§ã¯ãéæ£èŠã®gotoã䜿çšããå¿ èŠããããŸããããã¯ããžã£ã³ãã©ãã«ã®åŸã«äœ¿çšãããªããã®ãå«ã㊠ããã®åã«ãã¹ãŠã®å€æ°å®£èšãèšè¿°ããããšã匷å¶ããŸãã
var cnt int for ;; { goto NEXT a := int(0) // ./main.go:16: goto NEXT jumps over declaration of a at ./main.go:17 cnt += a NEXT: cnt ++ }
ãŸãããã€ã³ã¿ãŒãšéãã€ã³ã¿ãŒã®æ§æçµ±äžã®ãã©ãã€ã ã¯æ©èœããŸãã-æ§é äœã䜿çšããå Žåãã³ã³ãã€ã©ãŒã¯åãæ§æã䜿çšããæ©äŒãäžãããããã«ã-ãã©ã±ãããéåç §ããŠäœ¿çšããå¿ èŠããããŸãããã³ã³ãã€ã©ãŒã¯ãã¹ãŠã決å®ã§ããŸãïŒ
type T struct { cnt int } s := T{} p := new(T) s.cnt ++ p.cnt ++
ã§ã
m := make(map[int]T) p := new(map[int]T) *p = make(map[int]T) m[1] = T{} (*p)[1] = T{} p[1] = T{} // ./main.go:13: invalid operation: p[1] (type *map[int]T does not support indexing)
ãã§ã«äœæ¥ã®çµããã«ãæåã®ã¢ãŒããã¯ãã£ãééã£ãŠãããããæåã«å®è£ ãããæ©èœã®äžéšãæžãæããã®ã«æéãè²»ããå¿ èŠããããŸããã åŸãããçµéšã¯æ°ããã¢ãŒããã¯ãã£ã®ãã©ãã€ã ãæäŸããŸããããã®çµéšã¯ãŸã åŸãããå¿ èŠããããŸãïŒïŒ
ã¡ãªã¿ã«ãæåã®ã³ãŒãã®ç·éã¯ã»ãŒäžèŽããŠããŸããïŒPerlã®ã¹ããŒã¹ã¢ã©ã€ã³ã¡ã³ãã®å Žåã«ã®ã¿2ã€ã®ã¹ããŒã¹ã䜿çšãããGoã§ã¯1ã¿ãïŒãGoã®è¡ã¯20ïŒ å¢ããŸããã 確ãã«ãæ©èœã¯ãããã«ç°ãªããŸããGoã§ã¯ãããšãã°GCã§ã®äœæ¥ãè¿œå ãããŸãããPerlã§ã¯ãå€éšãã¡ã€ã«ãã£ãã·ã¥ã«SQLã¯ãšãªããã£ãã·ã¥ããããã«å¥ã®ã©ã€ãã©ãªãèæ ®ãããŸãïŒmmapïŒïŒçµç±ã®ã¢ã¯ã»ã¹ïŒã äžè¬ã«ãã³ãŒãã®éã¯ã»ãŒåãã§ãããPerlã¯ãŸã å°ãã³ã³ãã¯ãã§ãã ããããGoã«ã¯æ¬åŒ§ãšã»ãã³ãã³ãå°ãªã-ã³ãŒãã¯ããç°¡æœã§èªã¿ãããããã«èŠããŸãã
äžè¬ã«ãGoã³ãŒãã¯éåžžã«è¿ éãã€æ£ç¢ºã«èšè¿°ãããŠãããããšãã°C / C ++ããã¯ããã«é«éã§ãããç¹å¥ãªããã©ãŒãã³ã¹èŠä»¶ã®ãªãåçŽãªã¿ã¹ã¯ã®å Žåã¯ãPerlãåŒãç¶ã䜿çšããŸãã
æ§èœ
ççŽã«èšã£ãŠãããã©ãŒãã³ã¹ã«é¢ããŠGoã«ã€ããŠç¹ã«äžæºã¯ãããŸãããããã£ãšæåŸ ããŠããŸãã Perlãšã®éãïŒç®è¡ã§ã¯ãèšç®ã®çš®é¡ã«å€§ããäŸåããŸããããšãã°ãPerlã¯ãŸã£ããèŒããŸããïŒã¯çŽ5ã10åã§ãã ç§ã¯gccgoãè©Šãæ©äŒããããŸããã§ããã FreeBSDã§ã¯é£ãããããŸããããæ®å¿µã§ãã ããããããã¯ãšã³ããœãããŠã§ã¢ã¯ããã«ããã¯ã§ã¯ãªããªããCPUæ¶è²»ã¯1ã³ã¢ã®çŽ50ïŒ ã«ãªããè² è·ãå¢å ãããšãNginxãPostgreSQLãOSã§æåã«åé¡ãçºçããŸãã
ããã©ãŒãã³ã¹ãæé©åããéçšã§ããããã¡ã€ã©ãŒã¯ãã³ãŒãã«å ããŠãã©ã³ã¿ã€ã ãCPUã®ã¢ã¯ãã£ããªéšåãæ¶è²»ããããšã瀺ããŸããïŒããã¯ã©ã³ã¿ã€ã ããã±ãŒãžã«é¢ããã ãã§ã¯ãããŸããïŒã
top10 --cumã®äŸã次ã«ç€ºããŸãã
Total: 1945 samples 0 0.0% 0.0% 1309 67.3% runtime.gosched0 1 0.1% 0.1% 1152 59.2% bitbucket.org/mjl/scgi.func·002 1 0.1% 0.1% 1151 59.2% bitbucket.org/mjl/scgi.serve 0 0.0% 0.1% 953 49.0% net/http.HandlerFunc.ServeHTTP 3 0.2% 0.3% 952 48.9% main.ProcessHttpRequest 1 0.1% 0.3% 535 27.5% main.ProcessHttpRequestFromCache 0 0.0% 0.3% 418 21.5% main.ProcessHttpRequestFromDb 16 0.8% 1.1% 387 19.9% main.(*RequestRecord).SelectServerInDc 0 0.0% 1.1% 367 18.9% System 0 0.0% 1.1% 268 13.8% GC
ã芧ã®ãšãããæ¶è²»ãããCPUã®49ïŒ ã®ã¿ããã³ãã©ãŒã«ããå®éã®scgiãªã¯ãšã¹ãã®åŠçã«è²»ãããã33ïŒ ãã·ã¹ãã + GCã«è²»ããããŠããŸã
ãããŠãåããããã¡ã€ã«ã®top20ã次ã«ç€ºããŸãã
Total: 1945 samples 179 9.2% 9.2% 186 9.6% syscall.Syscall 117 6.0% 15.2% 117 6.0% runtime.MSpan_Sweep 114 5.9% 21.1% 114 5.9% runtime.kevent 93 4.8% 25.9% 96 4.9% runtime.cgocall 93 4.8% 30.6% 93 4.8% runtime.sys_umtx_op 67 3.4% 34.1% 152 7.8% runtime.mallocgc 63 3.2% 37.3% 63 3.2% runtime.duffcopy 56 2.9% 40.2% 99 5.1% hash_insert 56 2.9% 43.1% 56 2.9% scanblock 53 2.7% 45.8% 53 2.7% runtime.usleep 39 2.0% 47.8% 39 2.0% markonly 36 1.9% 49.7% 41 2.1% runtime.mapaccess2_fast32 28 1.4% 51.1% 28 1.4% runtime.casp 25 1.3% 52.4% 34 1.7% hash_init 23 1.2% 53.6% 23 1.2% hash_next 22 1.1% 54.7% 22 1.1% flushptrbuf 22 1.1% 55.8% 22 1.1% runtime.xchg 21 1.1% 56.9% 29 1.5% runtime.mapaccess1_fast32 21 1.1% 58.0% 21 1.1% settype 20 1.0% 59.0% 31 1.6% runtime.mapaccess1_faststr
ç§ã®ã³ãŒãã®èšç®ã¯ãã©ã³ã¿ã€ã ãåŠçããªããã°ãªããªãã¿ã¹ã¯ã®ããã¯ã°ã©ãŠã³ãã«å¯ŸããŠåçŽã«å€±ãããŸãïŒãããããããã¹ãã§ãããç§ã¯é£ããæ°åŠãæã£ãŠããŸããïŒã
ç§èŠãã³ã³ãã€ã©ãšã©ã€ãã©ãªãæé©åããããã®å€§ããªäºåããŸã ãããŸãã ããšãã°ãã€ã³ã©ã€ã³åã«æ°ä»ããŸããã§ãã-ãã¹ãŠã®mutexã¯goroutinã¹ã¿ãã¯ã®ã¹ã€ãŒãã§å®å šã«è¡šç€ºãããŸãã ã³ã³ãã€ã©ãŒã®æé©åããã»ã¹ã¯ãŸã æ¢ãŸããŸããïŒããã»ã©åã§ã¯ãããŸããããäŸãã°Dmitry Vyukovã¯ãã£ã³ãã«ã®å®è£ ãå€§å¹ ã«å éããŸãã ïŒãããããŸã§ã®ãšããã«ãŒãã£ãã«ã·ããã¯ããŸãç®ç«ã¡ãŸããã ããšãã°ãGo 1.2ããGo 1.3ã«åãæ¿ããåŸãããã©ãŒãã³ã¹ã®éãã¯ã»ãšãã©èŠãããŸããã§ããã
æé©åäžã§ãã£ãŠããmath / randããã±ãŒãžãæŸæ£ããå¿ èŠããããŸããã äºå®ãã¯ãšãªåŠçäžã«æ¬äŒŒä¹±æ°ãå¿ èŠã«ãªãããšãå€ãã£ãã®ã§ãããããŒã¿ãã€ã³ãã£ã³ã°ã§ã¯rand.SeedïŒïŒãCPUã䜿ããããŠããŸããïŒãããã¡ã€ã©ãŒã¯å šäœã®13ïŒ ã瀺ããŸããïŒã ãããå¿ èŠãšãã人ã¯èª°ã§ãé«éã·ãŒãïŒïŒã§æ¬äŒŒä¹±æ°ãçæããæ¹æ³ãã°ãŒã°ã«ã§æ€çŽ¢ããŸãããããã§ãæå·åã®ç®çã§æå·å/ã©ã³ãããã±ãŒãžããããæ°åŠ/ã©ã³ãã§ã¯åæåäžã«é«å質ã®ãããããã·ã³ã°ãããã»ã©æ°ã«ããªããããããŸããã
ãšããã§ãç§ã¯æ¬¡ã®ã¢ã«ãŽãªãºã ã«çŠç¹ãåœãŠãããšã«ãªããŸããã
func RandFloat64(seed uint64) float64 { seed ^= seed >> 12 seed ^= seed << 25 seed ^= seed >> 27 return float64((seed*2685821657736338717)&0x7fffffffffffffff) / (1 << 63) }
Perlã§ã¯ããã¹ãŠã®èšç®ã1ã€ã®ããã»ã¹ã§è¡ãããåå¥ã®ã¯ãŒã«ãŒããã»ã¹ã䜿çšãããmemcachedãä»ãããã®ããã¡ã€ã«ãä»ãããã®ãªã©ãå ±éã®ãã£ãã·ã¥ãæŽçããå¿ èŠããã£ãã®ã¯éåžžã«äŸ¿å©ã§ãã Goã§ã¯ãããã¯ã¯ããã«åçŽã§èªç¶ã§ãã ããããçŸåšãå€éšãã£ãã·ã¥ããªãå Žåãã³ãŒã«ãã¹ã¿ãŒãã®åé¡ãçºçããããã§å°ãæãå ããªããã°ãªããŸããã§ãã-æåã¯ãnginxã«å¶éããããšããŸããïŒäžåºŠã«10äžã®ãŽã«ãŒãã³ãéå§ãããå šäœãèµ·ããªãããã«ïŒ httpsïŒ//ã¢ãžã¥ãŒã«ãä»ããåæèŠæ±ã®æ°github.com/cfsego/nginx-limit-upstream ããããããã¯éåžžã«å®å®ããŠåäœããŸããã§ããïŒæ¥ç¶ããŒã«ãè©°ãŸããšãè² è·ãé€å»ããåŸã§ãéåžžã¢ãŒãã«æ»ãã®ãå€å°å°é£ã§ããïŒã ãã®çµæãscgiã¢ãžã¥ãŒã«ã«å°ãããããé©çšããåæã«å®è¡ããããªã¯ãšã¹ãã®æ°ã«ãªããã¿ãŒãè¿œå ããŸãã-çŸåšã®ãªã¯ãšã¹ãã®äžéšãåŠçããããŸã§ãæ°ãããªã¯ãšã¹ãã¯AcceptïŒïŒã§åãå ¥ããããŸãã-thïŒ
func ServeLimited(l net.Listener, handler http.Handler, limit int) error { if limit <= 0 { Serve(l, handler) } if l == nil { var err error l, err = net.FileListener(os.Stdin) if err != nil { return err } defer l.Close() } if handler == nil { handler = http.DefaultServeMux } sem := make(chan struct{}, limit) for { sem <- struct{}{} rw, err := l.Accept() if err != nil { return err } go func(rw net.Conn) { serve(rw, handler) <-sem }(rw) } }
scgiã¢ãžã¥ãŒã«ãããã©ãŒãã³ã¹äžã®çç±ã§éžæãããŸãã-äœããã®çç±ã§ãnet / http / fcgiã¯åãªãnet / httpãããé ãïŒæ°žç¶çãªæ¥ç¶ããµããŒãããŸããïŒãnet / httpã¯ããã«tcpãã±ããã®çæãšå éštcpæ¥ç¶ã®ãµããŒãã§OSãããŒãããŸããïŒæè¡çã«ã¯UNIXãœã±ããã§ãªãã¹ã³ãéå§ããããšã¯å¯èœã§ããïŒ-ãããŠããããåãé€ãããšãã§ããã®ã§ããªããããåãé€ããŸãããïŒ nginxãããã³ããšã³ããšããŠäœ¿çšãããšãã¿ã€ã ã¢ãŠãå¶åŸ¡ããã°èšé²ã倱æãããªã¯ãšã¹ããã¯ã©ã¹ã¿ãŒããä»ã®ãµãŒããŒã«è»¢éãããªã©ãæå°éã®ãµãŒããŒè² è·ã§ãã¹ãŠã®å©ç¹ãåŸãããŸãã ãã®ã¢ãããŒãã®ãã1ã€ã®ãã©ã¹-netstat -Lanã«ããã°ãAcciãã¥ãŒãscgiãœã±ããã§å¢å€§ããããšã確èªã§ããŸããããã¯ãã©ããã«ãªãŒããŒããŒãããããäœããããå¿ èŠãããããšãæå³ããŸãã
ã³ãŒãå質ãšãããã°
net / http / pprofããã±ãŒãžã¯éæ³ã®ãããªãã®ã§ãïŒ ããã¯ãApache server-statusã¢ãžã¥ãŒã«ã«äŒŒãŠããŸãããGoããŒã¢ã³çšã§ãã ãšããã§ãå°çšã®httpãã³ãã©ãŒã®ä»£ããã«DefaultServeMuxã䜿çšããå Žåã¯ãlink / debug / pprof /ãä»ããŠãã¹ãŠã®ãŠãŒã¶ãŒãããã±ãŒãžãå©çšã§ããããã«ãªããããå®çšŒåç°å¢ã«å«ããããšã¯ãå§ãããŸããã ããã©ããããhttpçµç±ã§ããã±ãŒãžé¢æ°ã«ã¢ã¯ã»ã¹ããã«ã¯ãlocalhostã§å¥ã®ãããµãŒããŒãå®è¡ããå¿ èŠããããŸãã
go func() { log.Println(http.ListenAndServe("127.0.0.1:8081", nil)) }()
ãã®ã¢ãžã¥ãŒã«ã¯ãããã»ããµãšã¡ã¢ãªã®ãããã¡ã€ã«ãååŸããããšã«å ããŠãçŸåšå®è¡äžã®ãã¹ãŠã®ãŽã«ãŒãã³ã®ãªã¹ãããããã§çŸåšå®è¡ãããŠããæ©èœã®ãã§ãŒã³å šäœãããã³ç¶æ ã衚瀺ããããšãå¯èœã«ããŸãïŒ/ debug / pprof / goroutine \ïŒããŸããŸãªãŽã«ãŒãã³ãšãã®ç¶æ ã®ãªã¹ããããã³/ debug / pprof / goroutine \ïŒdebug = 2ã¯ãå®è¡äžã®ãã¹ãŠã®ãŽã«ãŒãã³ã®ãªã¹ããæäŸããŸãã è€è£œïŒã€ãŸããå®å šã«åäžã®ç¶æ ïŒã ãããã®1ã€ã®äŸã次ã«ç€ºããŸãã
goroutine 85 [IO wait]: net.runtime_pollWait(0x800c71b38, 0x72, 0x0) /usr/local/go/src/pkg/runtime/netpoll.goc:146 +0x66 net.(*pollDesc).Wait(0xc20848daa0, 0x72, 0x0, 0x0) /usr/local/go/src/pkg/net/fd_poll_runtime.go:84 +0x46 net.(*pollDesc).WaitRead(0xc20848daa0, 0x0, 0x0) /usr/local/go/src/pkg/net/fd_poll_runtime.go:89 +0x42 net.(*netFD).accept(0xc20848da40, 0x8df378, 0x0, 0x800c6c518, 0x23) /usr/local/go/src/pkg/net/fd_unix.go:409 +0x343 net.(*UnixListener).AcceptUnix(0xc208273880, 0x8019acea8, 0x0, 0x0) /usr/local/go/src/pkg/net/unixsock_posix.go:293 +0x73 net.(*UnixListener).Accept(0xc208273880, 0x0, 0x0, 0x0, 0x0) /usr/local/go/src/pkg/net/unixsock_posix.go:304 +0x4b bitbucket.org/mjl/scgi.ServeLimited(0x800c7ec58, 0xc208273880, 0x800c6c898, 0x8df178, 0x1f4, 0x0, 0x0) /home/user/go/src/bitbucket.org/mjl/scgi/scgi.go:177 +0x20d main.func<C2><B7>008() /home/user/repo/main.go:264 +0x90 created by main.main /home/user/repo/main.go:265 +0x1f5c
ããã«ãããããã¯ã®ãããã°ãç¹å®ããããšãã§ããŸããïŒç¹å®ã®æ¡ä»¶äžã§ã¯ãRUnlockïŒïŒã2ååŒã³åºãããŸãããããããè¡ãããšã¯ã§ããŸããïŒ-ã¹ã¿ãã¯ã®ãã³ãã§ãããã¯ããããŽã«ãŒãã³ãšRUnlockïŒïŒãåŒã³åºãããè¡çªå·ã®æãèŠãŸããã
CPUãããã¡ã€ã«ãæªããããŸãããgvïŒghostviewïŒãã€ã³ã¹ããŒã«ããã«ãŠã³ã¿ãŒã䜿çšããé¢æ°éã®é·ç§»ã®Xorgãã€ã¢ã°ã©ã ã確èªããããšããå§ãããŸãã泚æããŠæé©åããå¿ èŠããããã®ã確èªã§ããŸãã
æçšãªãŠãŒãã£ãªãã£ã§ãããç§ã®äž»ãªå©ç¹ã¯ãããããçš®é¡ã®printfïŒïŒã®ãã©ãŒãããæå®åãèŠã€ãããªããšããèŠåã«ãªããŸãã-ã³ã³ãã€ã©ã¯ãããæ€åºã§ããŸããã æããã«æªãã³ãŒã
if UintValue < 0 { DoSomething() }
ç£å»ã¯ãŸã£ããåå¿ããŸããã
ã³ãŒãæ€èšŒã®äž»ãªäœæ¥ã¯ãã³ã³ãã€ã©ãŒã«ãã£ãŠå®è¡ãããŸãã 圌ã¯æªäœ¿çšã®å€æ°ãšããã±ãŒãžãå®æçã«èªããŸãããã³ã³ãã€ã©ãŒãç£å»ãæ§é å ã®æªäœ¿çšãã£ãŒã«ãã«åå¿ããŸããïŒå°ãªããšãèŠåã¯ãããŸãïŒã
æŒç®åã«ã¯æ³šæãå¿ èŠã§ãïŒ= ã 2ã€ã®uintã®å·®ãèšç®ããå¿ èŠãããå ŽåããããŸããã è² ã®å·®ãè² ãšæ£ããèŠãªããã³ãŒã
var a, b uint ... diff := a - b
ããªããæåŸ
ãããã®ã§ã¯ãªã-ããªãã¯çœ²åãããåãžã®å€æã䜿çšããå¿
èŠããããŸãïŒãŸãã¯çœ²åãªãã䜿çšããªãïŒ
åãããŒã¿åã«ç°ãªãç®çã§ç°ãªãååãä»ããããšããå§ãããŸãã ããšãã°ã次ã®ããã«ïŒ
type ServerIdType uint32 type CustomerIdType uint32 var ServerId ServerIdType var CustomerId CustomerIdType
ãããŠä»ãCustomerIdå€æ°ã«ã€ããŠã¯ãuint32å
ã«ååšããã«ãããããããã³ã³ãã€ã©ã¯ServerIdã®å€ãïŒã¿ã€ãå€æãªãã§ïŒæžã蟌ãããšãèš±å¯ããŸããã ç¹ã«å€æ°ãåæåããå Žåã¯ãåãã£ã¹ãã䜿çšããå¿
èŠããããŸãããããããã¿ã€ããã¹ã«åœ¹ç«ã¡ãŸãã
ããã±ãŒãžãã©ã€ãã©ãªãããã³Cã®æ
Goã®äººæ°ã§éèŠãªåœ¹å²ãæãããã®ã¯ãCã©ã€ãã©ãªãšå¯Ÿè©±ããããã®å¹æçãªïŒããã©ãŒãã³ã¹ã®é¢ã§ã¯ãªããããã€ãã®åé¡ãæ®ã£ãŠããïŒã¡ã«ããºã ã§ãã æŠããŠãGoã©ã€ãã©ãªã®éèŠãªéšåã¯ã察å¿ããCã©ã€ãã©ãªã®åãªãã©ãããŒã§ãã ããšãã°ãgithub.com / abh / geoipããã³github.com/jbarham/gopgsqldriverããã±ãŒãžã¯ããããã-lGeoIPããã³-lpqã§ã³ã³ãã€ã«ããŸãïŒå®éã«ã¯ããã€ãã£ãã®Go PostgreSQLãã©ã€ããŒ-github.com/lib/pqã䜿çšããŸãïŒã
ããšãã°ãunistd.hã®ã»ãŒæšæºã®cryptïŒïŒé¢æ°ãèããŠã¿ãŸããã-ãã®é¢æ°ã¯å€ãã®èšèªãããšãã°Nginx Perlã¢ãžã¥ãŒã«ã§ã¯ããã«äœ¿çšã§ããè¿œå ã®ã¢ãžã¥ãŒã«ãããŒãããã«äœ¿çšã§ããŸããããã¯äŸ¿å©ã§ãã ããããGoã§ã¯ãããã§ã¯èªåã§Cã«è»¢éããå¿ èŠããããŸãã ããã¯åºæ¬çãªæ¹æ³ã§è¡ãããŸãïŒäŸã§ã¯ãçµæãããœã«ããã«ãããããŸãïŒã
// #cgo LDFLAGS: -lcrypt // #include <unistd.h> // #include <stdlib.h> import "C" import ( "sync" "unsafe" ) var cryptMutex sync.Mutex func Crypt(str, salt string) string { cryptStr := C.CString(str) cryptSalt := C.CString(salt) cryptMutex.Lock() key := C.GoString(C.crypt(cryptStr, cryptSalt))[len(salt):] cryptMutex.Unlock() C.free(unsafe.Pointer(cryptStr)) C.free(unsafe.Pointer(cryptSalt)) return key }
ããã¯ãå¿
èŠã§ã cryptïŒïŒã¯åãchar *ãå
éšç¶æ
ã«è¿ããŸããåä¿¡ããæååã¯ã³ããŒããå¿
èŠããããŸããããã§ãªãå Žåã次ã®åŒã³åºãäžã«äžæžããããŸãã é¢æ°ã¯ã¹ã¬ããã»ãŒãã§ã¯ãããŸããã
ããŒã¿ããŒã¹/ SQL
䜿çšãããŠããåDbãã³ãã©ãŒã«ã€ããŠãåŒã³åºããŠæ¥ç¶ã®æ倧å¶éãç»é²ããã¢ã€ãã«æ¥ç¶ã®ãŒã以å€ã®å¶éãæå®ããããšããå§ãããŸãã
db.SetMaxOpenConns(30) db.SetMaxIdleConns(8)
1ã€ç®ã¯ããŒã¿ããŒã¹ã®éè² è·ãåé¿ããæ倧ããã©ãŒãã³ã¹ã¢ãŒãã§äœ¿çšããŸãïŒåææ¥ç¶æ°ã®å¢å ã«äŒŽããããŒã¿ããŒã¹ã®ããã©ãŒãã³ã¹ã¯ããæç¹ããäœäžãå§ããåæèŠæ±æ°ã«æé©ãªå€ããããŸãïŒã2ã€ç®ã¯æ°ããæ¥ç¶ãéãå¿
èŠæ§ãåãé€ããŸããã¹ãŠã®ã¯ãšãªãforkïŒïŒã¢ãŒãã®PostgreSQLã§ã¯ãããã¯ç¹ã«éèŠã§ãã ãã¡ãããPostgreSQLã®å Žåã¯ããŸã pgpoolãŸãã¯pgbouncerã䜿çšã§ããŸãããããã¯ã«ãŒãã«ã«ããããŒã¿éä¿¡ãšè¿œå ã®é
延ã®ããã®äœåãªãªãŒããŒãããã§ãããããã£ãŠãã¢ããªã±ãŒã·ã§ã³ã¬ãã«ã§æ¥ç¶ã®ç¶ç¶æ§ã確ä¿ããããšããå§ãããŸãã
ãªã¯ãšã¹ãã®è§£æãšèšç»ã®æ§ç¯ã®ãªãŒããŒããããé€å€ããã«ã¯ãçŽæ¥ãªã¯ãšã¹ãã®ä»£ããã«æºåæžã¿ã¹ããŒãã¡ã³ãã䜿çšããå¿ èŠããããŸãã ãã ããèŠããŠããå¿ èŠããããŸã-å Žåã«ãã£ãŠã¯ãã¯ãšãªå®è¡ã¹ã±ãžã¥ãŒã©ã¯ãæé©ãªãã©ã³ã䜿çšããªãå ŽåããããŸããããã¯ããªã¯ãšã¹ãã®å®è¡æ®µéã§ã¯ãªãããªã¯ãšã¹ãã®è§£æ段éã§æ§ç¯ãããã¹ã±ãžã¥ãŒã©ã«ã¯ã䜿çšããã®ã«é©ããã€ã³ããã¯ã¹ãç¥ãããã®ååãªããŒã¿ããªãå Žåãããããã§ã ãšããã§ãPostgreSQL Goãã©ã€ããŒã®å€æ°ã®ãã¬ãŒã¹ãã«ããŒã¯ãPerlã®ããã«ããïŒãã®ä»£ããã«ã$ 1ããã$ 2ããªã©ã䜿çšããŸãã
sqlãïŒè¡ïŒ.ScanïŒïŒã«ã¯1ã€ã®æ©èœããããŸã-DomainNameType stringãªã©ã®ååãå€æŽãããæååã¿ã€ããèªèããŸããã æåååã®äžæå€æ°ãéå§ããããŒã¿ããŒã¹ããããŒã¿ãããŒãããŠãããåå€æã䜿çšããŠå²ãåœãŠãè¡ãå¿ èŠããããŸãã äœããã®çç±ã§ãååãå€æŽãããæ°å€åã«ã¯ãã®ãããªåé¡ã¯ãããŸããã
ãã£ã³ãã«ãšåæ
Goã«ã¯ãã£ãã«ãããã®ã§ãããã ãã䜿çšãã䟡å€ããããšãã誀ã£ãæèŠããããŸãã ããã¯å®å šã«çå®ã§ã¯ãããŸãã-åã¿ã¹ã¯ã«ã¯ç¬èªã®ããŒã«ããããŸãã ãã£ãã«ã¯ããŸããŸãªçš®é¡ã®ã¡ãã»ãŒãžãéä¿¡ããã®ã«æé©ã§ãããsql-cacheãªã©ã®å ±æãªãœãŒã¹ãæäœããå Žåã¯ããã¥ãŒããã¯ã¹ã䜿çšããããšã¯éåžžã«åæ³ã§ãã ãã£ãã«ãä»ããŠãã£ãã·ã¥ãæäœããã«ã¯ã1ã€ã®ã³ã¢ãžã®ãã£ãã·ã¥ã¢ã¯ã»ã¹ã®ããã©ãŒãã³ã¹ãå¶éããã¯ãšãªãããŒãžã£ãŒãäœæããã·ã§ãã©ãŒãŽã«ãŒãã³ã«ããã«äœæ¥ãè¿œå ãããã£ãã«ã«ããŒã¿ãã³ããŒããã³èªã¿åãããã®ãªãŒããŒããããè¿œå ããå¿ èŠããããŸããããã«ãããŒã¿è»¢éçšã®äžæãã£ãã«ãäœæããå¿ èŠããããŸãããã¯ã³ãŒã«æ©èœã ãŸãããã£ãã«ã䜿çšããã³ãŒãã¯ãmutexã䜿çšããã³ãŒãã®äœåãè€éã«ãªããŸãïŒå¥åŠãªããšã«ïŒã ãããããã¥ãŒããã¯ã¹ã§ã¯ããããããã¯ã«é¥ããªãããã«éåžžã«æ³šæããå¿ èŠããããŸãã
Goã«ã¯struct {}ã®ãããªæ±ãã«ããæ©èœããããŸãã ã€ãŸã å®å šã«ç©ºã®æ§é ãããŒããŒã¬ã¹ã ããã¯ãŒãã¹ããŒã¹ãå æãããã®ãããªæ§é ã®ä»»æã®ãµã€ãºã®é åããŒãã¹ããŒã¹ãå æãã空ã®æ§é ã®ãããã¡ãªã³ã°ããããã£ã³ãã«ããŒãã¹ããŒã¹ãå æããŸãïŒãã¡ããå éšããŒã¿ãïŒã å®éã空ã®æ§é ã®ãã®ãããã¡ãªã³ã°ããããã£ãã«ã¯ã»ããã©ã§ãããã³ã³ãã€ã©ã§å¥ã®ãã³ãã©ãäœæãããŸã-Goæ§æã®ã»ããã©ãå¿ èŠãªå Žåã¯ã chan struct {}ã䜿çšã§ããŸãã
åæãã±ããã®æ²ãã¿ã¯å°ãæ²ããã§ãã ããšãã°ãã¹ãã³ããã¯ã¯ãããŸããããé«éã§ããããéåžžã«äŸ¿å©ã§ããïŒGCã䜿çšããå Žåãã¹ãã³ããã¯ã®äœ¿çšã¯ãªã¹ã¯ã®ããããžãã¹ã«ãªããŸãïŒã ããã«ããã¥ãŒããã¯ã¹èªäœã®æäœã¯ã€ã³ã©ã€ã³ã§ã¯ãããŸããïŒç§ãç¥ãéãïŒã ããã«ã€ã©ã€ã©ããã®ã¯ãRWMutexããã¯ãã¢ããã°ã¬ãŒãã§ããªãããšã§ã-ããã¯ãRLockã¹ããŒã¿ã¹ã«ãããå€æŽãå¿ èŠã§ããããšãå€æããå Žå-RUnlockïŒïŒãLockïŒïŒãå®è¡ãããããã®å€æŽãŸãã¯äœããã®ãŽã«ãŒãã³ã®å¿ èŠæ§ããŸã ãããã©ãããå床確èªããŠãã ããäœãšãã§ããŸããã ãã³ããããã³ã°ã®TryLockïŒïŒé¢æ°ããããŸããããªããã¯æ確ã§ã¯ãããŸãã-å Žåã«ãã£ãŠã¯éåžžã«å¿ èŠã§ãã ããã§ã¯ãèšèªã®éçºè ã§ãããããã°ã©ã ã®å¿ èŠæ§ãããç¥ã£ãŠããŸããIMHOãæ¢ã«è¡ãéããŠããŸãã
å Žåã«ãã£ãŠã¯ãã¢ãããã¯æäœãå«ãsync / atomicããã±ãŒãžã¯ããã¥ãŒããã¯ã¹ã®äœ¿çšãåé¿ããã®ã«åœ¹ç«ã¡ãŸãã ããšãã°ãã³ãŒãã§çŸåšã®uint32ã¿ã€ã ã¹ã¿ã³ãã䜿çšããããšããããããŸããã°ããŒãã«å€æ°ã«ä¿æããåãªã¯ãšã¹ãã®æåã«çŸåšã®å€ãã¢ãããã¯ã«ä¿åããŸãã å°ãæ±ãã¢ãããŒãããã«ããŒé¢æ°ãæžãããšã¯å¯èœã§ããããããã©ãŒãã³ã¹ã®ããã«ãã®ãããªç ç²ãæããªããã°ãªããªãããšããããŸã-ç¹å¥ãªå¶éãªãã§ãã®å€æ°ãç®è¡åŒã§äœ¿çšã§ããããã«ãªããŸããã
äžéšã®å ±éããŒã¿ã1ãæã§ã®ã¿ïŒããšãã°å®æçã«ïŒæŽæ°ãããå Žåããèªã¿åãå°çšã¢ãŒãã§äœ¿çšãããå Žåã«ã¯ãå¥ã®é©åãªæé©åæ¹æ³ããããŸãã äžçªäžã®è¡ã¯ãèªã¿åãæäœã®ããã«RLockïŒïŒ/ RUnlockïŒïŒãè¡ãå¿ èŠããªãããšã§ãïŒããã³æŽæ°ã®ããã«LockïŒïŒ/ UnlockïŒïŒïŒ-æŽæ°æ©èœã¯ããŒã¿ãæ°ããã¡ã¢ãªé åã«ããŒãããŠãããå€ãããŒã¿ãžã®ãã€ã³ã¿ãŒããã€ã³ã¿ãŒã§ã¢ãããã¯ã«çœ®ãæããããšãã§ããŸãæ°ãããã®ã«ã 確ãã«ãGoã§ã¯ãã¢ãããã¯ãã€ã³ã¿ãŒæžã蟌ã¿ã®æ©èœã«ã¯unsafe.Pointeråãå¿ èŠã§ããããã®èšèšããããã¯ããå¿ èŠããããŸãã
ãã ããããã¯ãå¿é ããããšãªããåŒã§ãã®ããŒã¿ã䜿çšã§ããŸãã ããã¯Goã«ãšã£ãŠç¹ã«éèŠã§ãã äžèŠçãããã¯ã¯ãå®éã«ã¯éåžžã«é·ããªãå¯èœæ§ããããŸãããããã¯ãã¹ãŠGCãåå ã§ããatomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&Data)), unsafe.Pointer(&newData))
GCïŒã¬ããŒãžã³ã¬ã¯ã¿ãŒïŒ
圌ã¯ç§ã®å±æ ¹ãããªã飲ã¿ãŸãã;ïŒãç¶æ³ãæ³åããŠãã ãã-è² è·ãã¹ããå®è¡ããŠ-ãã¹ãŠã¯å€§äžå€«ã§ããã©ã€ããã©ãã£ãã¯ãããŸããã-ãã¹ãŠãããŸããããŸãããããããã -ãããŠãã¹ãŠãæªããªãããéåžžã«æªãã§ã-å€ãèŠæ±ããã³ã°ããæ°ããèŠæ±ãå°çãïŒæ¯ç§æ°åïŒãã¢ããªã±ãŒã·ã§ã³ãåèµ·åããå¿ èŠããããŸãããã®åŸããã£ãã·ã¥ãè£å ããå¿ èŠãããããããã¹ãŠãåã³åæ¢ããŸãããå°ãªããšãæ©èœãããã°ããããŠããæ£åžžã«æ»ããŸããããããã®å®è¡æéã枬å®ããŸããèŠæ±åŠç段é-ããã³vi ããã¯ã䜿çšããªãã¹ããŒãžã§ãããŒã¿ããŒã¹ããã¡ã€ã«ãžã®ã¢ã¯ã»ã¹ã¯äœ¿çšãããããŒã«ã«èšç®ã®ã¿ãå®è¡ããéåžžã¯ãã€ã¯ãç§ã«åãŸãããã«ããã¹ãŠã®ã¹ããŒãžã®å®è¡æéãå®æçã«3ç§ä»¥äžã«ãžã£ã³ãããããšãæã¿ãŸããããã¯äœããã®å€çèŠå ã§ã¯ãªãããã©ãããã©ãŒã èªäœããŸãã¯ãããã¬ããŒãžã³ã¬ã¯ã¿ãŒã§ããã
Goã§ã¯ãruntime / debug.ReadGCStatsïŒïŒãä»ããŠGCããã©ãŒãã³ã¹çµ±èšã衚瀺ã§ããã®ã¯è¯ãããšã§ããé©ãã¹ãããšããããŸãã ç§ã®å Žåãæãã¢ã³ããŒãããããµãŒããŒã§ã¯ãGCã¯æ¬¡ã®ã¢ãŒãã§æ©èœããŸããã
0.06
0.30
2.00
0.06
0.30
2.00
...
æ°å€èªäœã¯ãããã«ç°ãªããŸããã倧ããã®é åºã¯ä¿æãããŸãã ããã¯ãGCã®å®è¡äžã«ã¢ããªã±ãŒã·ã§ã³ãã¹ãªãŒãç¶æ ã«ãªãæéã§ãããææ°ã®ãã®ãæäžéšã«ãããŸãã ãã¹ãŠã®äœæ¥ã2ç§éäžæåæ¢ããŸã-äœã§ããïŒ æãå¿ãããµãŒããŒã§äœãèµ·ãã£ãŠããã®ãæ³åããããšããæããŠããŸãããäœåãªããŠã³ã¿ã€ã ãçºçããªãããã«ãããã«è§ŠããŸããã§ããã
解決çã¯ãGCïŒïŒãããé »ç¹ã«å®è¡ããããšã§ããä¿¡é Œæ§ã®ããã«ãããã°ã©ã ããç¬ç«ããæ¹ãè¯ãã§ãã å®æçã«ã§ãã§ããŸãããå°ãæ··ä¹±ããŠãªã¯ãšã¹ãã«ãŠã³ã¿ãŒãäœæããå€ãããŒã¿ã®äž»èŠãªã¯ãªãŒã³ã¢ããåŸã«åŒ·å¶çã«GCïŒïŒãèµ·åããŸããããã®çµæãGCïŒïŒã¯æ°åã«1åã§ã¯ãªãã10ã20ç§ããšã«å®è¡ãéå§ããŸããããåãã¹ã¯çŽ0.1ç§ã§å®å®ããŠããããŸã£ããå¥ã®åé¡ã§ããåæã«ãããŒã¢ã³ã®ã¡ã¢ãªæ¶è²»éã20ïŒ æžå°ããŸãããã¬ããŒãžã³ã¬ã¯ã¿ãŒãå®å šã«ç¡å¹ã«ãããªãã·ã§ã³ããããŸãããããã¯çåœã®ããã°ã©ã ã«ã®ã¿é©ããŠãããããŒã¢ã³ã«ã¯é©ããŠããŸãããèšèªéçºè ã¯GCã«èšå®ãè¿œå ããŠãæå®ãããå¶éãããé·ãã¢ããªã±ãŒã·ã§ã³ãåæ¢ããªãã§ã代ããã«é »ç¹ã«å®è¡ãéå§ããå¿ èŠããããŸããããã«ãããé«è² è·ã®åé¡ããå€ãã®ãŠãŒã¶ãŒãç¯çŽã§ããŸãã
å°å³
ãããïŒPerlã«é¢ããŠããã·ã¥ïŒãéåžžã«æçšãªãã®ã§ãããšäž»åŒµãã人ã¯ããŸãããããããç§ã¯èšèªéçºè ã«å¯ŸããŠããããã®å®è£ ãšäœ¿çšæ¹æ³ã«ã€ããŠæ·±å»ãªäžæºãæã£ãŠããŸãã倧ãŸãã«èšã£ãŠããããã³ã³ãã€ã©ã䜿çšããã«ã¯ã次ã®3ã€ã®é¢æ°ã䜿çšããŸãã
. â , (.. , , ) âvalueType, ok := map_fetch(keyType) map_store(keyType, valueType) map_delete(keyType)
type T struct { cnt int } m := make(map[int]T) m[0] = T{} m[0].cnt++ // ./main.go:9: cannot assign to m[0].cnt
m[0], cnt .
m := make(map[int]*T) m[0] = new(T) m[0].cnt++
m := make(map[int]T) tmp := m[0] tmp.cnt++ m[0] = tmp
, â ( )
, , map_store
ãããã«è¿œå ãããå€ãã¡ã¢ãªå ã§ç§»åããªããšããå¶éãè¿œå ããŸãã*valueType = map_allocate(keyType)
map_allocateé¢æ°ã¯ãæ°ããäœæãããèŠçŽ ã ãã§ãªããå€æŽãããå Žåã¯æ¢åã®èŠçŽ ãžã®ãã€ã³ã¿ãååŸããããã«äœ¿çšããå¿ èŠããããŸãããã®ãã€ã³ã¿ãŒã䜿çšããŠãããã°ã©ããŒã«æ»ããå€ãæŽæ°ããåç §ã¡ãœãããåŒã³åºããŸããå€ãèšå®ãããŠããéã¯ããã¹ãŠæ£åžžã«æ©èœããŸãã
ãããå ã®å€ãžã®åç §ãååŸããæ©èœã¯ãããã«å®èšŒãããŠãããã¹ãŠã®èšèªã»ãã¥ãªãã£ãç Žå£ãããšäž»åŒµãã人ãããŸãããããããããã®å Žåãã»ãã¥ãªãã£ã¯ãšã«ããä¿èšŒãããŸãã-ãããã¯ããã«ç°ãªããŽã«ãŒãã³ãã䜿çšããããšã¯ã§ããŸãããããããªããšãèŠçŽ ã®æ¿å ¥äžã«å éšããŒã¿ãç Žå£ãããªã¹ã¯ããããŸããããã«ãããã°ã©ãã«å®å šã§ãªãããã±ãŒãžã䜿çšããã«ãããèŠçŽ ã®ã¢ãã¬ã¹ãååŸããå¿ èŠããããšèšã人ã¯ããŸãã-äžèšã®äŸã§ã¯ãã³ã³ãã€ã©ã¯ã¢ãã¬ã¹ãååŸããã«ãŠã³ã¿ãã€ã³ã¯ãªã¡ã³ããããã®ã¢ãã¬ã¹ãå¿ããããšãã§ããŸã-ããã¯ä»ã®ã©ãã«ãååŸã§ãããååãšããŠãããã誰ãååŸããŸããæäœã¯åœ±é¿ãåããŸããã
åé¡ãçºçããã®ã¯ãã¢ã€ãã ãåé€ããæªäœ¿çšã®ã¡ã¢ãªãžã®ãªã³ã¯ãåŒãç¶ã䜿çšããå Žåã®ã¿ã§ããããã¯ããããã¯ãªãã§ç°ãªããŽã«ãŒãã³ããã®ããããåæã«äœ¿çšããã®ãšåãé åããã§ã-ããã°ã©ããŒãããããªèªèº«ã§ããå Žåã圌ã®å»è ã¯èª°ã§ããïŒãŸããããã°ã©ã ãåé€ãããã¢ã€ãã ãžã®ã©ã€ããªã³ã¯ãæã£ãŠããéããåé€åŸã«ã¡ã¢ãªã解æŸãããªãããã«ãã¬ããŒãžã³ã¬ã¯ã¿ãŒããã®å Žåã«é©åãããããšãã§ããå Žåããã¹ãŠãæ£åžžã§ãããã»ãã¥ãªãã£äžã®åé¡ã¯ãããŸããã
ãŸãšã
æ²ããããªãäžçã«ã¯å®ç§ã¯ãããŸãããããããæ°ããèšèªãããã«çæ³çã«çãŸããããšãæåŸ ããã®ã¯åçŽã§ããã¯ããGoã«ã¯ããã€ãã®æ¬ ç¹ããããŸãããååãšããŠãããã¯ãã¹ãŠä¿®æ£å¯èœã§ãããèŠæããããŸããããããGoã¯ããã°ã©ãã³ã°èšèªã®éçºã次ã®ã¬ãã«ã«é²ãããã«ãã³ã¢ã³ã³ãã¥ãŒã¿ãŒã¢ãŒããã¯ãã£ã®çŸä»£ã®çŸå®ã«é©å¿ããé©åãªãã©ãã€ã ãææ¡ããŠããŸãã
éåžžã«é·ãéãç§ã¯æ°ããããã°ã©ãã³ã°èšèªãå匷ããŠããŸããããã€ãŠãç§ã¯CïŒFreeBSDã«ãŒãã«ã«ããããåœãŠãããã®ãããã®ã¬ãã«ïŒãPerlããã³ã·ã§ã«ã¹ã¯ãªããïŒäžè¬çãªã¿ã¹ã¯çšïŒãå°ãç¿åŸããŸãããPythonãRubyãJSã®åŠç¿ã«æ²¡é ããæéã欲æããããŸããã§ããããããã®èšèªã¯æ ¹æ¬çã«æ°ãããã®ãæäŸã§ãããã¢ã€ãã¢ãå€ããããšãã欲æ±ããããŸããã§ãããGoã¯ç§ã®ããŒã«ã»ãããå€§å¹ ã«è£å®ããããšãã§ããŸããã圌ã®ãã¹ãŠã®æ¬ ç¹ã«ã€ããŠãç§ã¯ãããå匷ããã®ã«è²»ãããæéãäžæ»ŽãåŸæããŠããŸãã-ããã¯æ¬åœã«äŸ¡å€ããããŸãã