제 인생에서 두 줄 트리를 쓴 게 몇 번째예요.
8468 단어 Go
개요
사람들은 인생에서 트리를 몇 번 쓴다고 한다. 그래서 몇 번째 트리에서 슈다치의 다츠-클론을 복제해 보았다. 트리의 기사가 많아서 여기서 Go에 이식해서 발견한 것들을 몇 가지 공유하고 싶다.
이번 결과: https://github.com/ikawaha/dartsclone
darts-clone
원소재는 이쪽.Java 버전과 Python 버전이 있습니다.
원소재는 이쪽.Java 버전과 Python 버전이 있습니다.
아무튼 해보겠습니다.
작업 원리와 구조를 고려하지 않고 복제를 시도했다. 이후 GO처럼 재구성했다. 자바 버전과 Python 버전의 코드를 왜 Go에 떨어뜨렸는지 흥미롭다.
재구성
사실 Darts-clone의 Go 버전이 이미 있습니다. 제작 후에야 알아차렸습니다.
https://github.com/euclidr/darts
이것은 마치 본가의 C++ 버전의 clone인 것 같아서 이것과 비교하였다.
벤치에서 찾아봤는데byte수조에서 쌍수조를 처리할 때와 unit32수조에서 쌍수조를 처리할 때 같은 처리를 하기 위해 두 가지 측면에서 함수를 정리했습니다.이 함수의 호출이 느려서 그런 것 같습니다. 이것을 여러 상황에서 가득 쓴 함수로 바꾸어 호출을 줄이면 속도가 대체적으로 같습니다.
변경 전:func (a MmapedDoubleArray) ExactMatchSearch(key string) (id, size int, err error) {
return exactMatchSearch(a, key) // ← 共通処理でまとめてた
}
변경 후: 손으로 변경func (a MmapedDoubleArray) ExactMatchSearch(key string) (id, size int, err error) {
nodePos := uint32(0)
unit, err := a.at(nodePos)
if err != nil {
return -1, -1, err
}
for i := 0; i < len(key); i++ {
nodePos ^= unit.offset() ^ uint32(key[i])
unit, err = a.at(nodePos)
if err != nil {
return -1, -1, err
}
if unit.label() != key[i] {
return -1, 0, nil
}
}
if !unit.hasLeaf() {
return -1, 0, nil
}
unit, err = a.at(nodePos ^ unit.offset())
if err != nil {
return -1, -1, err
}
return int(unit.value()), len(key), nil
}
이렇게 하면 비교 프로그램과 같은 성능을 가지지만, 비교 프로그램은 배열된 색인 검사 등 잘못된 검사를 생략하기 때문에 좀 빠르다. 하지만,오차 범위이기 때문에 오류 검사를 넣기로 했습니다. 패닉에서 멈추는 것은 미묘합니다.
mmap 지원
sudachi는 mmap에서 사전을 공유하고 메모리를 절약하는 데 사용할 수 있습니다. 따라서 sudachi에서 사용하는 darts-clone은 mmap를 지원합니다. GO에서도 mmap를 지원합니다. linux계와 윈도우즈의 대응이 바뀌기 때문에 테스트 등이 좀 번거롭습니다.darts-clone의 쌍수조 자체는byte열이기 때문에 솔직하게 대응하면 됩니다.
하지만 아무리 mmap로 읽을 때의 속도(1/10 정도)도 없다.
mmap를 사용하지 않는 상황에서 uint32의 배열로 두 배열을 나타냅니다. mmap를 사용할 때 이것은 작은 단자 순서의byte 배열입니다. 여기서 unit32의 값을 꺼냅니다.
처음에 쓴 코드는 Reader를 사용하여 위치를 지정한 후 Read()
읽은 것입니다. var ret uint32
if err := binary.Read(r, binary.LittleEndian, &ret); err != nil {
return 0, fmt.Errorf("read error, %v", err)
}
이 부분은 느린 것 같습니다. 이 배열을 직접 지정하고, if int(i+1)*unitSize > len(a.raw) {
return 0, fmt.Errorf("index out of bounds")
}
ret := binary.LittleEndian.Uint32(a.raw[i*unitSize : (i+1)*unitSize])
읽은 후, mmap 버전도 동등한 성능을 나타냈다.
그나저나 binary.LittleEndian.Uint32()
의 내용은,func (littleEndian) Uint32(b []byte) uint32 {
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
}
그렇군요. 간단합니다.
아, 그리고 syscall은 deprecated, golang입니다.org/x/sys 사용.
총결산
수다치에 해당하는darts-clonegithub.com/ikawaha/darts-clone을 발표했습니다. 이렇게 하면 사전을 찾는 기초 위에서 준비가 될 수 있기 때문에botchbotch와sudachi를 이식하고 싶습니다.
그나저나 작년부터 개발을 가로막았던 그거랑 이거랑 다 S로 갔는데 거기서 못 하는 벽에 부딪혀서 빼야 할 것 같지 않나. 이게 없으면 개발할 것 같은 느낌도 든다(^^`灬.
지난해부터 개발을 가로막고 있는 이것저것 → Happy hacking!
Reference
이 문제에 관하여(제 인생에서 두 줄 트리를 쓴 게 몇 번째예요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/ikawaha/items/edb4e18960ae6e4babc3
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
사실 Darts-clone의 Go 버전이 이미 있습니다. 제작 후에야 알아차렸습니다.
https://github.com/euclidr/darts
이것은 마치 본가의 C++ 버전의 clone인 것 같아서 이것과 비교하였다.
벤치에서 찾아봤는데byte수조에서 쌍수조를 처리할 때와 unit32수조에서 쌍수조를 처리할 때 같은 처리를 하기 위해 두 가지 측면에서 함수를 정리했습니다.이 함수의 호출이 느려서 그런 것 같습니다. 이것을 여러 상황에서 가득 쓴 함수로 바꾸어 호출을 줄이면 속도가 대체적으로 같습니다.
변경 전:
func (a MmapedDoubleArray) ExactMatchSearch(key string) (id, size int, err error) {
return exactMatchSearch(a, key) // ← 共通処理でまとめてた
}
변경 후: 손으로 변경func (a MmapedDoubleArray) ExactMatchSearch(key string) (id, size int, err error) {
nodePos := uint32(0)
unit, err := a.at(nodePos)
if err != nil {
return -1, -1, err
}
for i := 0; i < len(key); i++ {
nodePos ^= unit.offset() ^ uint32(key[i])
unit, err = a.at(nodePos)
if err != nil {
return -1, -1, err
}
if unit.label() != key[i] {
return -1, 0, nil
}
}
if !unit.hasLeaf() {
return -1, 0, nil
}
unit, err = a.at(nodePos ^ unit.offset())
if err != nil {
return -1, -1, err
}
return int(unit.value()), len(key), nil
}

이렇게 하면 비교 프로그램과 같은 성능을 가지지만, 비교 프로그램은 배열된 색인 검사 등 잘못된 검사를 생략하기 때문에 좀 빠르다. 하지만,오차 범위이기 때문에 오류 검사를 넣기로 했습니다. 패닉에서 멈추는 것은 미묘합니다.
mmap 지원
sudachi는 mmap에서 사전을 공유하고 메모리를 절약하는 데 사용할 수 있습니다. 따라서 sudachi에서 사용하는 darts-clone은 mmap를 지원합니다. GO에서도 mmap를 지원합니다. linux계와 윈도우즈의 대응이 바뀌기 때문에 테스트 등이 좀 번거롭습니다.darts-clone의 쌍수조 자체는byte열이기 때문에 솔직하게 대응하면 됩니다.
하지만 아무리 mmap로 읽을 때의 속도(1/10 정도)도 없다.
mmap를 사용하지 않는 상황에서 uint32의 배열로 두 배열을 나타냅니다. mmap를 사용할 때 이것은 작은 단자 순서의byte 배열입니다. 여기서 unit32의 값을 꺼냅니다.
처음에 쓴 코드는 Reader를 사용하여 위치를 지정한 후 Read()
읽은 것입니다. var ret uint32
if err := binary.Read(r, binary.LittleEndian, &ret); err != nil {
return 0, fmt.Errorf("read error, %v", err)
}
이 부분은 느린 것 같습니다. 이 배열을 직접 지정하고, if int(i+1)*unitSize > len(a.raw) {
return 0, fmt.Errorf("index out of bounds")
}
ret := binary.LittleEndian.Uint32(a.raw[i*unitSize : (i+1)*unitSize])
읽은 후, mmap 버전도 동등한 성능을 나타냈다.
그나저나 binary.LittleEndian.Uint32()
의 내용은,func (littleEndian) Uint32(b []byte) uint32 {
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
}
그렇군요. 간단합니다.
아, 그리고 syscall은 deprecated, golang입니다.org/x/sys 사용.
총결산
수다치에 해당하는darts-clonegithub.com/ikawaha/darts-clone을 발표했습니다. 이렇게 하면 사전을 찾는 기초 위에서 준비가 될 수 있기 때문에botchbotch와sudachi를 이식하고 싶습니다.
그나저나 작년부터 개발을 가로막았던 그거랑 이거랑 다 S로 갔는데 거기서 못 하는 벽에 부딪혀서 빼야 할 것 같지 않나. 이게 없으면 개발할 것 같은 느낌도 든다(^^`灬.
지난해부터 개발을 가로막고 있는 이것저것 → Happy hacking!
Reference
이 문제에 관하여(제 인생에서 두 줄 트리를 쓴 게 몇 번째예요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/ikawaha/items/edb4e18960ae6e4babc3
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
var ret uint32
if err := binary.Read(r, binary.LittleEndian, &ret); err != nil {
return 0, fmt.Errorf("read error, %v", err)
}
if int(i+1)*unitSize > len(a.raw) {
return 0, fmt.Errorf("index out of bounds")
}
ret := binary.LittleEndian.Uint32(a.raw[i*unitSize : (i+1)*unitSize])
func (littleEndian) Uint32(b []byte) uint32 {
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
}
수다치에 해당하는darts-clonegithub.com/ikawaha/darts-clone을 발표했습니다. 이렇게 하면 사전을 찾는 기초 위에서 준비가 될 수 있기 때문에botchbotch와sudachi를 이식하고 싶습니다.
그나저나 작년부터 개발을 가로막았던 그거랑 이거랑 다 S로 갔는데 거기서 못 하는 벽에 부딪혀서 빼야 할 것 같지 않나. 이게 없으면 개발할 것 같은 느낌도 든다(^^`灬.
지난해부터 개발을 가로막고 있는 이것저것 → Happy hacking!
Reference
이 문제에 관하여(제 인생에서 두 줄 트리를 쓴 게 몇 번째예요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ikawaha/items/edb4e18960ae6e4babc3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)