perf: 予測変換候補の検索において早期に打ち切ることで高速化

This commit is contained in:
Miwa / Ensan
2025-03-16 15:30:23 +09:00
parent 42fdba530f
commit 1409575391
3 changed files with 21 additions and 10 deletions

View File

@@ -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

View File

@@ -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))
}

View File

@@ -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)
}
///