Address
:
[go:
up one dir
,
main page
]
Include Form
Remove Scripts
Accept Cookies
Show Images
Show Referer
Rotate13
Base64
Strip Meta
Strip Title
Session Cookies
Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
pt&Goroutines
Search
monochromegane
May 31, 2014
Technology
20
15k
pt&Goroutines
pt(the_platinum_searcher) を高速化するために Goroutines まわりで試したことを発表しました。
http://connpass.com/event/6370/
monochromegane
May 31, 2014
Tweet
Share
More Decks by monochromegane
See All by monochromegane
Go言語での実装を通して学ぶLLMファインチューニングの仕組み / fukuokago22-llm-peft
monochromegane
0
150
不確実性下における目的と手段の統合的探索に向けた連続腕バンディットの応用 / iot70_gp_rff_mab
monochromegane
2
200
なめらかなシステムと運用維持の終わらぬ未来 / dicomo2025_coherently_fittable_system
monochromegane
0
4.3k
ベクトル検索システムの気持ち
monochromegane
37
11k
Go言語での実装を通して学ぶ、高速なベクトル検索を支えるクラスタリング技術/fukuokago-kmeans
monochromegane
1
220
Go言語でターミナルフレンドリーなAIコマンド、afaを作った/fukuokago20_afa
monochromegane
2
300
多様かつ継続的に変化する環境に適応する情報システム/thesis-defense-presentation
monochromegane
1
1.1k
Online Nonstationary and Nonlinear Bandits with Recursive Weighted Gaussian Process
monochromegane
0
720
AIを前提とした体験の実現に向けて/toward_ai_based_experiences
monochromegane
2
1.1k
Other Decks in Technology
See All in Technology
Retrospectiveを振り返ろう
nakasho
0
150
様々なファイルシステム
sat
PRO
0
280
アノテーション作業書作成のGood Practice
cierpa0905
PRO
1
350
オブザーバビリティと育てた ID管理・認証認可基盤の歩み / The Journey of an ID Management, Authentication, and Authorization Platform Nurtured with Observability
kaminashi
2
1.6k
GPUをつかってベクトル検索を扱う手法のお話し~NVIDIA cuVSとCAGRA~
fshuhe
0
320
re:Invent 2025の見どころと便利アイテムをご紹介 / Highlights and Useful Items for re:Invent 2025
yuj1osm
0
540
20251027_findyさん_音声エージェントLT
almondo_event
2
520
Kotlinで型安全にバイテンポラルデータを扱いたい! ReladomoラッパーをAIと実装してみた話
itohiro73
3
140
データとAIで明らかになる、私たちの課題 ~Snowflake MCP,Salesforce MCPに触れて~ / Data and AI Insights
kaonavi
0
220
設計に疎いエンジニアでも始めやすいアーキテクチャドキュメント
phaya72
24
15k
NOT A HOTEL SOFTWARE DECK (2025/11/04)
notahotel
0
240
AIでデータ活用を加速させる取り組み / Leveraging AI to accelerate data utilization
okiyuki99
6
1.6k
Featured
See All Featured
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
116
20k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
140
34k
Gamification - CAS2011
davidbonilla
81
5.5k
Learning to Love Humans: Emotional Interface Design
aarron
274
41k
Building a Modern Day E-commerce SEO Strategy
aleyda
44
7.9k
Art, The Web, and Tiny UX
lynnandtonic
303
21k
Thoughts on Productivity
jonyablonski
71
4.9k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.6k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
37
2.6k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
2
210
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
9
940
Measuring & Analyzing Core Web Vitals
bluesmoon
9
650
Transcript
pt &Goroutine - GoCon 2014 spring -
MIYAKE Yusuke (@monochromegane)
GMO Pepabo, Inc.
grep ͯ͠·͔͢ʁ
grep?
ack?
ag?
pt The Platinum Searcher
Written in Golang
Mac OSX Linux Windows
UTF-8 EUC-JP Shift-JIS
AND
fast ! ack go 6.24s user 1.06s system 99% cpu
7.304 total # ack ag go 0.88s user 1.39s system 221% cpu 1.027 total # ag pt go 1.09s user 1.01s system 235% cpu 0.892 total # pt
How?
Goroutine & Channel
͍ͬ͠ΐʹߴԽͯ͠Έ·͠ΐ͏
1. ϑΝΠϧΛݕࡧͯ͠(find) 2. จࣈྻΛݕࡧͯ͠(grep) 3. ݁ՌΛදࣔ͢Δ(print) ύλʔϯݕࡧͱ
Approach-0 ! ॱ൪ʹ
find
find grep
find grep print
// find find := find.Find{Option: self.Option} find.Do(self.Root) ! // grep
grep := grep.Grep{ Files: find.Files, // result Pattern: self.Pattern, Option: self.Option} grep.Do() ! // print print := print.Print{ Matches: grep.Matches, // result Pattern: self.Pattern, Option: self.Option} print.Do()
> the_simple_searcher go $GOROOT > /dev/null
0.79 seconds
Approach-1 ! ฒߦʹ
Goroutine
• GoݴޠͰฒߦॲཧΛ࣮ݱ͢Δ • εϨουɺίϧʔνϯͱҧ͏ • Concurrency(ฒߦ)ͱParallelism(ฒྻ) • ܰྔ • go
f()
find grep print go go go
Channel
• Goroutineؒͷϝοηʔδϯά • ͷૹड৴ • όοϑΝʹΑΔϒϩοΫ
find grep print go go go
$IBOFM find grep print $IBOFM go go go
$IBOFM find grep print $IBOFM go go go
// channel files := make(chan *string, self.Option.Cap) matches := make(chan
*grep.Match, self.Option.Cap) done := make(chan bool) ! // find find := find.Find{Files: files, Option: self.Option} go find.Do(self.Root) ! // grep grep := grep.Grep{ Files: files, Matches: matches, Pattern: self.Pattern, Option: self.Option} go grep.Do() ! // print print := print.Print{ Done: done, Matches: matches, Pattern: self.Pattern, Option: self.Option} go print.Do() ! <-done // block
walkFunc := func(path string, info os.FileInfo, err error) error {
if info.IsDir() { return nil } self.Files <- &path // send return nil } ! filepath.Walk(root, walkFunc) close(self.Files) // close
for file := range self.Files { // receive ( <-self.Files
) fh, err := os.Open(*file) if err != nil { panic(err) } ! f := bufio.NewReader(fh) ! var buf []byte var lineNum = 1 for { buf, _, err = f.ReadLine() if err != nil { break } line := string(buf) if strings.Contains(line, self.Pattern) { self.Matches <- &Match{*file, lineNum, line} // send } lineNum++ } fh.Close() } close(self.Matches) // close
for match := range self.Matches { // receive fmt.Printf("%s:%d:%s\n", match.Path,
match.Num, match.Match) } self.Done <- true // send
> the_simple_searcher go $GOROOT > /dev/null
0.79 -> 0.87 seconds
?
buffer
• Channelͷड༰ྔ • ch := make(chan ܕ, ༰ྔ) • ༰ྔ·Ͱड
• ༰ྔ͑Δͱૹ৴ଆडͪ • ड৴͢Δͱ༰ྔ͕ͻͱۭͭ͘ • ༰ྔ͕0ͷ߹ɺৗʹͭ
// channel with buffer files := make(chan *string, self.Option.Cap) matches
:= make(chan *grep.Match, self.Option.Cap) done := make(chan bool) // always wait
> the_simple_searcher go $GOROOT > /dev/null
0.79 -> 0.8 seconds
Approach-2 ! ͬͱฒߦʹ
$IBOFM find grep print $IBOFM go go go
$IBOFM find grep print $IBOFM go go go grep grep
grep
var wg sync.WaitGroup for file := range self.Files { wg.Add(1)
// goroutineͷىಈΛΠϯΫϦϝϯτ (தུ) go func(self *Grep, file *string) { defer wg.Done() // goroutine͕ྃͨ͠ΒىಈΛσΫϦϝϯτ for { ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ(தུ) } fh.Close() ! }(self, file) // ΫϩʔδϟΛgoroutineʹ͢Δͱ͖มͷڞ༗ʹҙ ! } wg.Wait() // ෆಛఆͷgoroutine͕શͯऴྃ͢ΔͷΛͭ close(self.Matches)
> the_simple_searcher go $GOROOT > /dev/null
panic ! too many open files
var wg sync.WaitGroup sem := make(chan bool, self.Option.Cap) // ىಈ͢ΔgoroutineͷΛ੍ޚ͢Δchannel
for file := range self.Files { sem <- true // goroutineͷىಈ(channelͷbuffer)͕͍ͬͺ͍ͳΒͭ wg.Add(1) (தུ) go func(self *Grep, file *string) { defer wg.Done() for { ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ(தུ) } fh.Close() <-sem // ಉ࣌ىಈchannelͷbufferʹۭ͖Λͭ͘Δ ! }(self, file) ! } wg.Wait() close(self.Matches)
> the_simple_searcher go $GOROOT > /dev/null
0.79 -> 0.8 seconds
Approach-3 ! ฒྻʹ
GOMAXPROCS
• Goroutineͷฒྻ • σϑΥϧτ1 • runtime.NumCPU()ͰίΞΛऔಘ • runtime.GOMAXPROCS()ͰฒྻΛઃఆ
> the_simple_searcher go $GOROOT > /dev/null
0.79 -> 0.55 ! seconds
benchmark ! • Mac OSX(10.9.3) • CPU: 2.5GHz Core i5(2Core)
• Memory: 8GB • Go: 1.2.2
#V⒎FS (0."9130$4 "QQSPBDI
ฒߦԽͯ͠ͳ͍ͷͰ ฒྻԽͯ͠มΘΒͣ ίΞҎ্ͷࢦఆ ޮՌͳ͠ ଌఆͯ͠ௐ͠ͳ͍ͱ ߹ʹΑͬͯ͘ͳΔ #V⒎FS (0."9130$4 "QQSPBDI
–Rob Pike • Concurrency is powerful. • Concurrency is not
parallelism. • Concurrency enables parallelism. • Concurrency makes parallelism (and scaling and everything else) easy.
એ ϖύϘͰΤϯδχΞΛืू͍ͯ͠·͢ɻ ڞʹαʔϏεΛੜΈग़͠ҭͯͯ͘ΕΔ৽͍ؒ͠ Λ͍ͬͯ·͢ɻ ! http://pepabo.com/recruit/career/engineer/
͓ΘΓ