This Week In Go commits(2017/3/20〜) #golang
3/20~3/28のコミットから取り上げています。 中国や京都に旅行していたらコミットが溜まってしまっていました…
cmd/compile: don’t merge load+op if other op arg is still live
#19595に関連する変更です。
通常であればload
と op
を
l = LOAD ptr mem y = OP x l into y = OPload x ptr mem
と、1つの命令に統合したいのですが、すべてのOPload命令ではy
はx
と同じレジスタを使用する必要があります。 x
がこの命令の後に必要な場合は、x
を他の場所にコピーしなければならず、命令を最初に統合する利点が失われます。そのため、他のop
引数がまだ生きていれば、上記の最適化を無効にしてload
とop
を統合しないようにしています。
Commit Message
cmd/compile: don't merge load+op if other op arg is still live We want to merge a load and op into a single instruction l = LOAD ptr mem y = OP x l into y = OPload x ptr mem However, all of our OPload instructions require that y uses the same register as x. If x is needed past this instruction, then we must copy x somewhere else, losing the whole benefit of merging the instructions in the first place. Disable this optimization if x is live past the OP. Also disable this optimization if the OP is in a deeper loop than the load. Update #19595 Change-Id: I87f596aad7e91c9127bfb4705cbae47106e1e77a Reviewed-on: https://go-review.googlesource.com/38337 Reviewed-by: Ilya Tocar <ilya.tocar@intel.com>
net/rpc: Create empty maps and slices as return type
#19588に対する修正です。
package main import ( "fmt" "log" "net" "net/rpc" "net/rpc/jsonrpc" ) type Arith int type Result int func (t *Arith) Multiply(args int, result *Result) error { return nil } func (t *Arith) DoMap(args int, result *map[string]string) error { *result = map[string]string{} return nil } func (t *Arith) DoMap2(args int, result *map[string]string) error { return nil } func main() { go runServer() client, err := jsonrpc.Dial("tcp", fmt.Sprintf("127.0.0.1:9001")) if err != nil { log.Fatal(err.Error()) } var reply Result err = client.Call("Arith.Multiply", 1, &reply) if err != nil { log.Fatal(err.Error()) } fmt.Println("call Multiply success") var ret map[string]string err = client.Call("Arith.DoMap", 1, &ret) if err != nil { log.Fatal(err.Error()) } fmt.Println("call DoMap success") err = client.Call("Arith.DoMap2", 1, &ret) if err != nil { log.Fatal(err.Error()) } fmt.Println("call DoMap2 success") } func runServer() { arith := new(Arith) rpc.Register(arith) tcpAddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:9001") if err != nil { fmt.Println("ResolveTCPAddr error:", tcpAddr, err.Error()) return } listener, err := net.ListenTCP("tcp", tcpAddr) if err != nil { fmt.Println("listen tcp error:", tcpAddr, err.Error()) return } for { conn, err := listener.Accept() if err != nil { continue } jsonrpc.ServeConn(conn) } }
以前はこのコードに対してinvalid error <nil>
が返ってしまっていました。
原因として、map
またはslice
を戻り値の型として使用する場合に、server.readRequest
で返すreflect.Value
がnil
で返っていたため、このCLによって空の値を作成して返すようにすることで解決されました。
Commit Message
net/rpc: Create empty maps and slices as return type When a map or slice is used as a return type create an empty value rather than a nil value. Fixes #19588 Change-Id: I577fd74956172329745d614ac37d4db8f737efb8 Reviewed-on: https://go-review.googlesource.com/38474 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
os: parse command line without shell32.dll
#15588に対する修正です。
Goではコマンドラインのパラメータをパースするのにshell32.dll
からCommandLineToArgV
を使用していますがshell32.dll
は読み込みが遅いため、Windows向けにshell32.dll
の使用を避けたコマンドライン解析を実装し、Goプログラムの起動を速くしています。
ベンチマークは以下の通りです
name | old time/op | new time/op | delta |
---|---|---|---|
RunningGoProgram-2 | 11.2ms ± 1% | 10.4ms ± 2% -6.63% | (p=0.000 n=9+10) |
on my Windows XP 386:
name | old time/op | new time/op | delta |
---|---|---|---|
RunningGoProgram-2 | 19.0ms ± 3% | 12.1ms ± 1% -36.20% | (p=0.000 n=10+10) |
on @egonelbre Windows 10 amd64:
name | old time/op | new time/op | delta |
---|---|---|---|
RunningGoProgram-8 | 17.0ms ± 1% | 15.3ms ± 2% -9.71% | (p=0.000 n=10+10) |
Commit Message
os: parse command line without shell32.dll Go uses CommandLineToArgV from shell32.dll to parse command line parameters. But shell32.dll is slow to load. Implement Windows command line parsing in Go. This should make starting Go programs faster. I can see these speed ups for runtime.BenchmarkRunningGoProgram on my Windows 7 amd64: name old time/op new time/op delta RunningGoProgram-2 11.2ms ± 1% 10.4ms ± 2% -6.63% (p=0.000 n=9+10) on my Windows XP 386:=,. name old time/op new time/op delta RunningGoProgram-2 19.0ms ± 3% 12.1ms ± 1% -36.20% (p=0.000 n=10+10) on @egonelbre Windows 10 amd64: name old time/op new time/op delta RunningGoProgram-8 17.0ms ± 1% 15.3ms ± 2% -9.71% (p=0.000 n=10+10) This CL is based on CL 22932 by John Starks. Fixes #15588. Change-Id: Ib14be0206544d0d4492ca1f0d91fac968be52241 Reviewed-on: https://go-review.googlesource.com/37915 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
net/http: strip port from host in mux Handler
#10463に関連するCLです。
handlerとのマッチングを試みる前にリクエストのhost
にport
が含まれているかをチェックし、含まれている場合にはmux.Handler
のport
を削除してpath
をクリーンアップします。
CONNECTリクエストに関しては、path
とhost
は変更されずに使用されます。
Commit Message
net/http: strip port from host in mux Handler This change strips the port in mux.Handler before attempting to match handlers and adds a test for a request with port. CONNECT requests continue to use the original path and port. Fixes #10463 Change-Id: Iff3a2ca2b7f1d884eca05a7262ad6b7dffbcc30f Reviewed-on: https://go-review.googlesource.com/38194 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
cmd/compile: disable typPtr caching in the backend
#15756に関連する変更です。 このIssueではビルドの高速化に向けて並行コンパイルを行うように多くの変更がされています。今回のCLはその中の一つです。(josharianが他にも多くのCLを出していますが、多すぎで全てを扱うことができませんでした。詳しくはIssueのほうをご覧になってください)
通常、* T
を生成するときには、結果のTypeをT
にキャッシュして後で再作成しないようにしますが、そのキャッシュが concurrency-safeではありませんでした。その対応としてこのCLでは mutex
を用いるのではなく、処理を開始する前にキャッシングを無効にすることで低コストでのconcurrency-safeを実現しています。
また、一般的に使用される* Ts
をあらかじめ作成しておくと、新たに* Ts
を生成するコストがあまりないため、パフォーマンスの悪化を一層防ぐことができます。
ベンチマークは以下の通りです。
name | old alloc/op | new alloc/op | delta |
---|---|---|---|
Template | 40.3MB ± 0% | 40.4MB ± 0% | +0.18% (p=0.001 n=10+10) |
Unicode | 29.8MB ± 0% | 29.8MB ± 0% | +0.11% (p=0.043 n=10+9) |
GoTypes | 114MB ± 0% | 115MB ± 0% | +0.33% (p=0.000 n=9+10) |
SSA | 855MB ± 0% | 859MB ± 0% | +0.40% (p=0.000 n=10+10) |
Flate | 25.7MB ± 0% | 25.8MB ± 0% | +0.35% (p=0.000 n=10+10) |
GoParser | 31.9MB ± 0% | 32.1MB ± 0% | +0.58% (p=0.000 n=10+10) |
Reflect | 79.6MB ± 0% | 79.9MB ± 0% | +0.31% (p=0.000 n=10+10) |
Tar | 26.9MB ± 0% | 26.9MB ± 0% | +0.21% (p=0.000 n=10+10) |
XML | 42.5MB ± 0% | 42.7MB ± 0% | +0.52% (p=0.000 n=10+9) |
name | old allocs/op | new allocs/op | delta |
---|---|---|---|
Template | 394k ± 1% | 393k ± 0% | ~ (p=0.529 n=10+10) |
Unicode | 319k ± 1% | 319k ± 0% | ~ (p=0.720 n=10+9) |
GoTypes | 1.15M ± 0% | 1.15M ± 0% | +0.14% (p=0.035 n=10+10) |
SSA | 7.53M ± 0% | 7.56M ± 0% | +0.45% (p=0.000 n=9+10) |
Flate | 238k ± 0% | 238k ± 1% | ~ (p=0.579 n=10+10) |
GoParser | 318k ± 1% | 320k ± 1% | +0.64% (p=0.001 n=10+10) |
Reflect | 1.00M ± 0% | 1.00M ± 0% | ~ (p=0.393 n=10+10) |
Tar | 254k ± 0% | 254k ± 1% | ~ (p=0.075 n=10+10) |
XML | 395k ± 0% | 397k ± 0% | +0.44% (p=0.001 n=10+9) |
Commit Message
cmd/compile: disable typPtr caching in the backend The only new Types that the backend introduces are pointers to Types generated by the frontend. Usually, when we generate a *T, we cache the resulting Type in T, to avoid recreating it later. However, that caching is not concurrency safe. Rather than add mutexes, this CL disables that caching before starting the backend. The backend generates few enough new *Ts that the performance impact of this is small, particularly if we pre-create some commonly used *Ts. Updates #15756 name old alloc/op new alloc/op delta Template 40.3MB ± 0% 40.4MB ± 0% +0.18% (p=0.001 n=10+10) Unicode 29.8MB ± 0% 29.8MB ± 0% +0.11% (p=0.043 n=10+9) GoTypes 114MB ± 0% 115MB ± 0% +0.33% (p=0.000 n=9+10) SSA 855MB ± 0% 859MB ± 0% +0.40% (p=0.000 n=10+10) Flate 25.7MB ± 0% 25.8MB ± 0% +0.35% (p=0.000 n=10+10) GoParser 31.9MB ± 0% 32.1MB ± 0% +0.58% (p=0.000 n=10+10) Reflect 79.6MB ± 0% 79.9MB ± 0% +0.31% (p=0.000 n=10+10) Tar 26.9MB ± 0% 26.9MB ± 0% +0.21% (p=0.000 n=10+10) XML 42.5MB ± 0% 42.7MB ± 0% +0.52% (p=0.000 n=10+9) name old allocs/op new allocs/op delta Template 394k ± 1% 393k ± 0% ~ (p=0.529 n=10+10) Unicode 319k ± 1% 319k ± 0% ~ (p=0.720 n=10+9) GoTypes 1.15M ± 0% 1.15M ± 0% +0.14% (p=0.035 n=10+10) SSA 7.53M ± 0% 7.56M ± 0% +0.45% (p=0.000 n=9+10) Flate 238k ± 0% 238k ± 1% ~ (p=0.579 n=10+10) GoParser 318k ± 1% 320k ± 1% +0.64% (p=0.001 n=10+10) Reflect 1.00M ± 0% 1.00M ± 0% ~ (p=0.393 n=10+10) Tar 254k ± 0% 254k ± 1% ~ (p=0.075 n=10+10) XML 395k ± 0% 397k ± 0% +0.44% (p=0.001 n=10+9) Change-Id: I6c031ed4f39108f26969c5712b73aa2fc08cd10a Reviewed-on: https://go-review.googlesource.com/38417 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
runtime: introduce a type for lfstacks
リファクタのためにlfstacks
型を導入しています。
lfstack
はロックフリーなstackの先頭を表すuint64
であり、lfstack
のゼロ値は空のリストです。node
は最初のフィールドとしてlfnode
を埋め込む必要があります。stackはGC可視のポインタをnode
に保持しないので、呼び出し元はnode
がGCされないようにする必要があります。(通常は手動で管理されるメモリから割り当てます)
push
、pop
、およびempty
のメソッドを持つlfstack型を作成することで、CLで書かれているコードのようなGoらしいコードを書くことができます。
Commit Message
runtime: introduce a type for lfstacks The lfstack API is still a C-style API: lfstacks all have unhelpful type uint64 and the APIs are package-level functions. Make the code more readable and Go-style by creating an lfstack type with methods for push, pop, and empty. Change-Id: I64685fa3be0e82ae2d1a782a452a50974440a827 Reviewed-on: https://go-review.googlesource.com/38290 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
runtime: disallow malloc or panic in scavenge
scavenge
でのMallocsとパニックはmheap.lock
上でセルフデッドロックする可能性を孕んでいます。そのため、このCLではヒープロック状態でのmalloc
やpanic
を禁止しています。
Commit Message
runtime: disallow malloc or panic in scavenge Mallocs and panics in the scavenge path are particularly nasty because they're likely to silently self-deadlock on the mheap.lock. Avoid sinking lots of time into debugging these issues in the future by turning these into immediate throws. Change-Id: Ib36fdda33bc90b21c32432b03561630c1f3c69bc Reviewed-on: https://go-review.googlesource.com/38293 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
cmd/compile/internal/syntax: add position info for { and } braces
{}
括弧の位置情報を追加しています。 syntax.Nodes
のメモリ使用量が約1.9%増加しますが、コンパイラ全体のメモリ使用量から見ると無視できる程度です。
Commit Message
cmd/compile/internal/syntax: add position info for { and } braces This change adds position information for { and } braces in the source. There's a 1.9% increase in memory use for syntax.Nodes, which is negligible relative to overall compiler memory consumption. Parsing the std library (using syntax package only) and memory consumption before this change (fastest of 5 runs): $ go test -run StdLib -fast parsed 1516827 lines (3392 files) in 780.612335ms (1943124 lines/s) allocated 379.903Mb (486.673Mb/s) After this change (fastest of 5 runs): $ go test -run StdLib -fast parsed 1517022 lines (3394 files) in 793.487886ms (1911840 lines/s) allocated 387.086Mb (267B/line, 487.828Mb/s) While not an exact apples-to-apples comparison (the syntax package has changed and is also parsed), the overall impact is small. Also: Small improvements to nodes_test.go. Change-Id: Ib8a7f90bbe79de33d83684e33b1bf8dbc32e644a Reviewed-on: https://go-review.googlesource.com/38435 Reviewed-by: Matthew Dempsky <mdempsky@google.com>
strconv: optimize decimal ints formatting with smallsString
#19445に関する変更です。
smallsString
を使用して10進整数をフォーマットするように変更されています。
以前のCLで1~99の小さなdecimal ints
についてキャッシュを用いて高速化を図っていたものの続きです。
GOARCH
= amd64
でのベンチマーク結果は以下の通りです。
name | old time/op | new time/op | delta |
---|---|---|---|
FormatInt-4 | 2.51µs ± 2% | 2.40µs ± 2% | -4.51% (p=0.000 n=9+10) |
AppendInt-4 | 1.67µs ± 2% | 1.61µs ± 3% | -3.74% (p=0.000 n=9+9) |
FormatUint-4 | 698ns ± 2% | 643ns ± 3% | -7.95% (p=0.000 n=10+8) |
AppendUint-4 | 478ns ± 1% | 418ns ± 2% | -12.61% (p=0.000 n=8+10) |
AppendUintVarlen/1-4 | 9.30ns ± 6% | 9.15ns ± 1% | ~ (p=0.199 n=9+10) |
AppendUintVarlen/12-4 | 9.12ns ± 0% | 9.16ns ± 2% | ~ (p=0.307 n=9+9) |
AppendUintVarlen/123-4 | 18.6ns ± 2% | 18.7ns ± 0% | ~ (p=0.091 n=10+6) |
AppendUintVarlen/1234-4 | 19.1ns ± 4% | 17.7ns ± 1% | -7.35% (p=0.000 n=10+9) |
AppendUintVarlen/12345-4 | 21.5ns ± 3% | 20.7ns ± 3% | -3.78% (p=0.002 n=9+10) |
AppendUintVarlen/123456-4 | 23.5ns ± 3% | 20.9ns ± 1% | -11.14% (p=0.000 n=10+9) |
AppendUintVarlen/1234567-4 | 25.0ns ± 2% | 23.6ns ± 7% | -5.48% (p=0.004 n=9+10) |
AppendUintVarlen/12345678-4 | 26.8ns ± 2% | 23.4ns ± 2% | -12.79% (p=0.000 n=9+10) |
AppendUintVarlen/123456789-4 | 29.8ns ± 3% | 26.5ns ± 5% | -11.03% (p=0.000 n=10+10) |
AppendUintVarlen/1234567890-4 | 31.6ns ± 3% | 26.9ns ± 3% | -14.95% (p=0.000 n=10+9) |
AppendUintVarlen/12345678901-4 | 33.8ns ± 3% | 29.3ns ± 5% | -13.21% (p=0.000 n=10+10) |
AppendUintVarlen/123456789012-4 | 35.5ns ± 4% | 29.2ns ± 4% | -17.82% (p=0.000 n=10+10) |
AppendUintVarlen/1234567890123-4 | 37.6ns ± 4% | 31.4ns ± 3% | -16.48% (p=0.000 n=10+10) |
AppendUintVarlen/12345678901234-4 | 39.8ns ± 6% | 32.0ns ± 7% | -19.60% (p=0.000 n=10+10) |
AppendUintVarlen/123456789012345-4 | 40.7ns ± 0% | 34.4ns ± 4% | -15.55% (p=0.000 n=6+10) |
AppendUintVarlen/1234567890123456-4 | 45.4ns ± 6% | 35.1ns ± 4% | -22.66% (p=0.000 n=10+10) |
AppendUintVarlen/12345678901234567-4 | 45.1ns ± 1% | 36.7ns ± 4% | -18.77% (p=0.000 n=9+10) |
AppendUintVarlen/123456789012345678-4 | 46.9ns ± 0% | 36.4ns ± 3% | -22.49% (p=0.000 n=9+10) |
AppendUintVarlen/1234567890123456789-4 | 50.6ns ± 6% | 38.8ns ± 3% | -23.28% (p=0.000 n=10+10) |
AppendUintVarlen/12345678901234567890-4 | 51.3ns ± 2% | 38.4ns ± 0% | -25.00% (p=0.000 n=9+8) |
Commit Message
strconv: optimize decimal ints formatting with smallsString Benchmark results for GOARCH=amd64: name old time/op new time/op delta FormatInt-4 2.51µs ± 2% 2.40µs ± 2% -4.51% (p=0.000 n=9+10) AppendInt-4 1.67µs ± 2% 1.61µs ± 3% -3.74% (p=0.000 n=9+9) FormatUint-4 698ns ± 2% 643ns ± 3% -7.95% (p=0.000 n=10+8) AppendUint-4 478ns ± 1% 418ns ± 2% -12.61% (p=0.000 n=8+10) AppendUintVarlen/1-4 9.30ns ± 6% 9.15ns ± 1% ~ (p=0.199 n=9+10) AppendUintVarlen/12-4 9.12ns ± 0% 9.16ns ± 2% ~ (p=0.307 n=9+9) AppendUintVarlen/123-4 18.6ns ± 2% 18.7ns ± 0% ~ (p=0.091 n=10+6) AppendUintVarlen/1234-4 19.1ns ± 4% 17.7ns ± 1% -7.35% (p=0.000 n=10+9) AppendUintVarlen/12345-4 21.5ns ± 3% 20.7ns ± 3% -3.78% (p=0.002 n=9+10) AppendUintVarlen/123456-4 23.5ns ± 3% 20.9ns ± 1% -11.14% (p=0.000 n=10+9) AppendUintVarlen/1234567-4 25.0ns ± 2% 23.6ns ± 7% -5.48% (p=0.004 n=9+10) AppendUintVarlen/12345678-4 26.8ns ± 2% 23.4ns ± 2% -12.79% (p=0.000 n=9+10) AppendUintVarlen/123456789-4 29.8ns ± 3% 26.5ns ± 5% -11.03% (p=0.000 n=10+10) AppendUintVarlen/1234567890-4 31.6ns ± 3% 26.9ns ± 3% -14.95% (p=0.000 n=10+9) AppendUintVarlen/12345678901-4 33.8ns ± 3% 29.3ns ± 5% -13.21% (p=0.000 n=10+10) AppendUintVarlen/123456789012-4 35.5ns ± 4% 29.2ns ± 4% -17.82% (p=0.000 n=10+10) AppendUintVarlen/1234567890123-4 37.6ns ± 4% 31.4ns ± 3% -16.48% (p=0.000 n=10+10) AppendUintVarlen/12345678901234-4 39.8ns ± 6% 32.0ns ± 7% -19.60% (p=0.000 n=10+10) AppendUintVarlen/123456789012345-4 40.7ns ± 0% 34.4ns ± 4% -15.55% (p=0.000 n=6+10) AppendUintVarlen/1234567890123456-4 45.4ns ± 6% 35.1ns ± 4% -22.66% (p=0.000 n=10+10) AppendUintVarlen/12345678901234567-4 45.1ns ± 1% 36.7ns ± 4% -18.77% (p=0.000 n=9+10)
regexp: reduce allocs in regexp.Match for onepass regex
onepass
な正規表現に対するregexp.Match
内のアロケーションを削減しています。
ベンチマークを見てもわかる通りかなりの速度改善になっています。
regexp.Matchのncap = 0
としてあるため、onepass
でない正規表現においてはregexp.Match
の割り当てはありませんが、onepass
な正規表現の場合、ncap = 0
であってもm.matchcap
の長さはそのままであるため無駄なアロケーションが発生してしまっていました。
benchmark | old ns/op | new ns/op | delta |
---|---|---|---|
BenchmarkMatch_onepass_regex/32-4 | 6465 | 4628 | -28.41% |
BenchmarkMatch_onepass_regex/1K-4 | 208324 | 151558 | -27.25% |
BenchmarkMatch_onepass_regex/32K-4 | 7230259 | 5834492 | -19.30% |
BenchmarkMatch_onepass_regex/1M-4 | 234379810 | 166310682 | -29.04% |
BenchmarkMatch_onepass_regex/32M-4 | 7903529363 | 4981119950 | -36.98% |
benchmark | old MB/s | new MB/s | speedup |
---|---|---|---|
BenchmarkMatch_onepass_regex/32-4 | 4.95 | 6.91 | 1.40x |
BenchmarkMatch_onepass_regex/1K-4 | 4.92 | 6.76 | 1.37x |
BenchmarkMatch_onepass_regex/32K-4 | 4.53 | 5.62 | 1.24x |
BenchmarkMatch_onepass_regex/1M-4 | 4.47 | 6.30 | 1.41x |
BenchmarkMatch_onepass_regex/32M-4 | 4.25 | 6.74 | 1.59x |
Commit Message
regexp: reduce allocs in regexp.Match for onepass regex There were no allocations in regexp.Match for *non* onepass regex because m.matchcap length is reset to zero (ncap=0 for regexp.Match). But, as for onepass regex, m.matchcap length remains as it is even when ncap=0 and it leads needless allocations. benchmark old ns/op new ns/op delta BenchmarkMatch_onepass_regex/32-4 6465 4628 -28.41% BenchmarkMatch_onepass_regex/1K-4 208324 151558 -27.25% BenchmarkMatch_onepass_regex/32K-4 7230259 5834492 -19.30% BenchmarkMatch_onepass_regex/1M-4 234379810 166310682 -29.04% BenchmarkMatch_onepass_regex/32M-4 7903529363 4981119950 -36.98% benchmark old MB/s new MB/s speedup BenchmarkMatch_onepass_regex/32-4 4.95 6.91 1.40x BenchmarkMatch_onepass_regex/1K-4 4.92 6.76 1.37x BenchmarkMatch_onepass_regex/32K-4 4.53 5.62 1.24x BenchmarkMatch_onepass_regex/1M-4 4.47 6.30 1.41x BenchmarkMatch_onepass_regex/32M-4 4.25 6.74 1.59x benchmark old allocs new allocs delta BenchmarkMatch_onepass_regex/32-4 32 0 -100.00% BenchmarkMatch_onepass_regex/1K-4 1024 0 -100.00% BenchmarkMatch_onepass_regex/32K-4 32768 0 -100.00% BenchmarkMatch_onepass_regex/1M-4 1048576 0 -100.00% BenchmarkMatch_onepass_regex/32M-4 104559255 0 -100.00% benchmark old bytes new bytes delta BenchmarkMatch_onepass_regex/32-4 512 0 -100.00% BenchmarkMatch_onepass_regex/1K-4 16384 0 -100.00% BenchmarkMatch_onepass_regex/32K-4 524288 0 -100.00% BenchmarkMatch_onepass_regex/1M-4 16777216 0 -100.00% BenchmarkMatch_onepass_regex/32M-4 2019458128 0 -100.00% Fixes #19573 Change-Id: I033982d0003ebb0360bb40b92eb3941c781ec74d Reviewed-on: https://go-review.googlesource.com/38270 Run-TryBot: Michael Matloob <matloob@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Go commit 流し読み(2017/3/12)
Goでその日Mergeされたもののうち、ある程度大きいものを取り上げていきます。 tenntennさんの影響でGoにcontributeして以降せっかく毎日commitを追っているから、ということでy_yagiさんをリスペクトして始めましたが、毎日続けるのはつらそうなので気の向いたときに記事にしようと思います。(要望があればがんばるかもしれません)
cmd/vet: eliminate “might be too small for shift” warnings
Issueに対する修正です。
func f(i int) int { return i >> 32 }
以前までは上記のコードにあるようなマシン依存型である int
, uint
, uintptr
に対して、vetが might be too small for shift
という警告を出してしまっていました。
この変更によって、GOARCH
環境変数が設定されている場合はそこから int
,uint
,uintptr
のビットサイズを決定し、それ以外の場合にはホスト固有のサイズを使用するようになりました。
strconv: fix performance regression in integer formatting on 32bit platforms
32ビットプラットフォームでの整数フォーマットのパフォーマンス改善をしています。この変更は64bitプラットフォームにはほとんど影響がありません。
strconv: use % instead of computing the remainder from the quotientに関連したCLです。
上記のCLでは、1つのDIV命令の場合にコンパイラが /
と %
を順番に認識すると想定していました。
しかし、別々のランタイムの関数を使用して除算とモジュロを計算している32bitプラットフォーム上の64bitオペランドでは順番に認識されるとは限りません。
そのため、上記のCLで消されてしまった32bitプラットフォームで有益な最適化を復元しています。
ベンチマークは以下の通りです。
386
name | old time/op | new time/op | delta |
---|---|---|---|
FormatInt-2 | 6.06µs ± 0% | 6.02µs ± 0% | -0.70% | (p=0.000 n=20+20) |
AppendInt-2 | 4.98µs ± 0% | 4.98µs ± 0% | ~ |(p=0.747 n=18+18) |
FormatUint-2 | 1.93µs ± 0% | 1.85µs ± 0% | -4.19%| (p=0.000 n=20+20) |
AppendUint-2 | 1.71µs ± 0% | 1.64µs ± 0% | -3.68%| (p=0.000 n=20+20) |
amd64
name | old time/op | new time/op | delta |
---|---|---|---|
FormatInt-2 | 2.41µs ± 0% | 2.41µs ± 0% | -0.09% | (p=0.010 n=18+18) |
AppendInt-2 | 1.77µs ± 0% | 1.77µs ± 0% | +0.08% | (p=0.000 n=18+18) |
FormatUint-2 | 653ns ± 1% | 653ns ± 0% | ~ |(p=0.178 n=20+20) |
AppendUint-2 | 514ns ± 0% | 513ns ± 0% | -0.13% | (p=0.000 n=20+17) |
無償の愛は果たして存在するのか?〜少し学問的に考えてみた〜
はじめに
大学の友達と食堂で話していたら恋愛の話しになり、気づいたら「無償の愛が存在するのかどうか」という話になっていた。 20分程度の議論ではあったが、そのまま忘れ去ってしまうのももったいないので備忘録程度に残しておく。
この議論には絶対的結論があるわけではないので、反論などあればぜひ(建設的な)議論をしたいです。
無条件に人を愛するとは
今回は無償の愛を「相手の存在全てを愛すること」「一切見返りを求めずに愛すること」として、様々な観点で無償の愛について見ていった。
アインシュタイン
突然だが、僕がアインシュタインを愛していたとする。 「アインシュタイン」という文字列は名前なのだが、この「アインシュタイン」という固有名詞は
- 男性
- 相対性理論を提唱
- 天才物理学者
などといったその人を表す言葉の集まりと同等であると考えられていた。 ただ、この「男性」という特徴が「女性」になったからといって「アインシュタイン」は「アインシュタイン」たる存在であることには変わりない。 よって、「アインシュタイン」を「アインシュタイン」たらしめる独自性のようなものは、それらの特徴の否定の契機を孕んでいるといえる。 つまり「アインシュタイン」という存在はは彼の持つ特徴を表現している一方で、むしろその否定の契機をも含むものである。
そのため、僕が「アインシュタイン」を無条件に愛していると言った時、それは彼が女性であろうと、天才物理学者でなかろうと、その存在を愛していなければならない。 それが人を愛すると言うことである。
僕にはとうていそんなことはできそうにない。
贈与論
次に、贈与論の立場から話しをすることになった。 愛も「愛してるよ。」「私も愛してるわ。」という贈与の関係だと言える。
無条件の愛というものは見返りを求めない愛、とも言い換えられるので、もし見返りを求めて「愛しているよ。」と言っているのであればそれは無償の愛とは言えない。 ただ、残念なことに贈与の関係において、最初の一方的な贈与は存在しないとする考えがある。 どういうことかというと、どちらかが最初に告白をして「愛してるよ。」と言い始めたとしても、それは見返りを求めない贈与ではないということである。なぜなら、告白以前に相手が「自分に気があるかも」と思わせるような行動をして気付かぬうちに贈与をしていたり、自分の中に相手がつきあいたいなと思えるような魅力を持っていてそれを見返りとして期待していたりするからである。つまり、告白という行為は少なからず以前に贈与を得ていたり、その後の贈与を期待するものなのである。
マザーテレサ
無償の愛、といえばこのマザーテレサを思い浮かべる方も多いだろう。 wikipediaにも
テレサは授賞式の際にも特別な正装はせず、普段と同じく白い木綿のサリーと皮製のサンダルという粗末な身なりで出席した。賞金19万2000ドルは全てカルカッタの貧しい人々のために使われることになった上、授賞式の場においては、「私のための晩餐会は不要です。その費用はどうか貧しい人々のためにお使い下さい」とも要望した。賞金を受け取った時、「このお金でいくつのパンが買えますか」と言ったという。
と書いてあり、ノーベル賞にも選ばれていることからも一見無償の愛を体現しているかに思える。 ただ、残念なことにテレサの行動の背景には宗教的「神」の存在があり、カトリック信者であるため、神のため、という意図が働いている。そのため完全な「無償の愛」であるとは言いがたいのである。
そのほか、親の愛も無償の愛にちかいのではないかという声もあったが、親も「子供をしっかり育てている親である」という社会的ラベルの為の愛ではないかという結論に達し、無償の愛ではないという判断となった。(実際僕も親に「自分の子供自慢の為に教育費をかけてあげている」「その分良い大学、良い会社にいってくれ」といった事を言われたことがある。正直な親である。)
結論、結局人間は 「愛している自分を愛するため」か「愛されているので愛す」という形でしか愛することができないのではないか という結論に達した。
まあこんな感じで我々は「この世界に無償の愛は存在しない」という悲しい結論に達し、とぼとぼと試験勉強に向かったのであった。
(10分くらいで書いたので誤植や論理の飛躍があるかもしれませんがその辺りはご了承ください。)