mirror of
https://github.com/mii443/AzooKeyKanaKanjiConverter.git
synced 2025-12-03 02:58:27 +00:00
perf: 予測変換候補の検索において早期に打ち切ることで高速化
This commit is contained in:
@@ -54,7 +54,7 @@ extension Subcommands.Dict {
|
||||
return
|
||||
}
|
||||
// ありったけ取り出す
|
||||
let nodeIndices = louds.prefixNodeIndices(chars: [], maxDepth: .max)
|
||||
let nodeIndices = louds.prefixNodeIndices(chars: [], maxDepth: .max, maxCount: .max)
|
||||
let store = DicdataStore(convertRequestOptions: self.requestOptions())
|
||||
let result = store.getDicdataFromLoudstxt3(identifier: self.target, indices: nodeIndices)
|
||||
var filteredResult = result
|
||||
|
||||
@@ -240,11 +240,11 @@ public final class DicdataStore {
|
||||
return Array(result[min(depth.lowerBound + 1, result.endIndex) ..< min(depth.upperBound + 1, result.endIndex)])
|
||||
}
|
||||
|
||||
private func prefixMatchLOUDS(query: String, charIDs: [UInt8], depth: Int = .max) -> [Int] {
|
||||
private func prefixMatchLOUDS(query: String, charIDs: [UInt8], depth: Int = .max, maxCount: Int = .max) -> [Int] {
|
||||
guard let louds = self.loadLOUDS(query: query) else {
|
||||
return []
|
||||
}
|
||||
return louds.prefixNodeIndices(chars: charIDs, maxDepth: depth)
|
||||
return louds.prefixNodeIndices(chars: charIDs, maxDepth: depth, maxCount: maxCount)
|
||||
}
|
||||
|
||||
package func getDicdataFromLoudstxt3(identifier: String, indices: some Sequence<Int>) -> [DicdataElement] {
|
||||
@@ -567,6 +567,7 @@ public final class DicdataStore {
|
||||
return []
|
||||
}
|
||||
// 最大700件に絞ることによって低速化を回避する。
|
||||
let maxCount = 700
|
||||
var result: [DicdataElement] = []
|
||||
let first = String(key.first!)
|
||||
let charIDs = key.map(self.character2charId)
|
||||
@@ -578,16 +579,16 @@ public final class DicdataStore {
|
||||
} else {
|
||||
Int.max
|
||||
}
|
||||
let prefixIndices = self.prefixMatchLOUDS(query: first, charIDs: charIDs, depth: depth).prefix(700)
|
||||
let prefixIndices = self.prefixMatchLOUDS(query: first, charIDs: charIDs, depth: depth, maxCount: maxCount)
|
||||
|
||||
result.append(
|
||||
contentsOf: self.getDicdataFromLoudstxt3(identifier: first, indices: Set(prefixIndices))
|
||||
.filter { Self.predictionUsable[$0.rcid] }
|
||||
)
|
||||
let userDictIndices = self.prefixMatchLOUDS(query: "user", charIDs: charIDs, depth: depth).prefix(700)
|
||||
let userDictIndices = self.prefixMatchLOUDS(query: "user", charIDs: charIDs, maxCount: maxCount)
|
||||
result.append(contentsOf: self.getDicdataFromLoudstxt3(identifier: "user", indices: Set(consume userDictIndices)))
|
||||
if learningManager.enabled {
|
||||
let memoryDictIndices = self.prefixMatchLOUDS(query: "memory", charIDs: charIDs).prefix(700)
|
||||
let memoryDictIndices = self.prefixMatchLOUDS(query: "memory", charIDs: charIDs, maxCount: maxCount)
|
||||
result.append(contentsOf: self.getDicdataFromLoudstxt3(identifier: "memory", indices: Set(consume memoryDictIndices)))
|
||||
result.append(contentsOf: self.learningManager.temporaryPrefixMatch(charIDs: charIDs))
|
||||
}
|
||||
|
||||
@@ -165,13 +165,23 @@ package struct LOUDS: Sendable {
|
||||
return index
|
||||
}
|
||||
|
||||
@inlinable func prefixNodeIndices(nodeIndex: Int, depth: Int = 0, maxDepth: Int) -> [Int] {
|
||||
@inlinable func prefixNodeIndices(nodeIndex: Int, depth: Int = 0, maxDepth: Int, maxCount: Int) -> [Int] {
|
||||
var childNodeIndices = Array(self.childNodeIndices(from: nodeIndex))
|
||||
if depth == maxDepth {
|
||||
return childNodeIndices
|
||||
}
|
||||
for index in childNodeIndices {
|
||||
childNodeIndices.append(contentsOf: self.prefixNodeIndices(nodeIndex: index, depth: depth + 1, maxDepth: maxDepth))
|
||||
if childNodeIndices.count > maxCount {
|
||||
break
|
||||
}
|
||||
childNodeIndices.append(
|
||||
contentsOf: self.prefixNodeIndices(
|
||||
nodeIndex: index,
|
||||
depth: depth + 1,
|
||||
maxDepth: maxDepth,
|
||||
maxCount: maxCount - childNodeIndices.count
|
||||
)
|
||||
)
|
||||
}
|
||||
return childNodeIndices
|
||||
}
|
||||
@@ -182,11 +192,11 @@ package struct LOUDS: Sendable {
|
||||
/// - Parameter chars: CharIDに変換した文字列
|
||||
/// - Parameter maxDepth: 先に進む深さの最大値
|
||||
/// - Returns: 対応するloudstxt3ファイル内のインデックスのリスト
|
||||
@inlinable package func prefixNodeIndices(chars: [UInt8], maxDepth: Int) -> [Int] {
|
||||
@inlinable package func prefixNodeIndices(chars: [UInt8], maxDepth: Int, maxCount: Int) -> [Int] {
|
||||
guard let nodeIndex = self.searchNodeIndex(chars: chars) else {
|
||||
return []
|
||||
}
|
||||
return self.prefixNodeIndices(nodeIndex: nodeIndex, maxDepth: maxDepth)
|
||||
return self.prefixNodeIndices(nodeIndex: nodeIndex, maxDepth: maxDepth, maxCount: maxCount)
|
||||
}
|
||||
|
||||
/// 部分前方一致検索を実行する
|
||||
|
||||
Reference in New Issue
Block a user