feat: configurable chapter window & parallel metadata parsing with benchmark
1. Configurable chapter window size (onDemandChapterWindowSize: 3-15) - Parameterized window radius in RDEPUBChapterRuntimeStore - Updated RDEPUBChapterWindowCoordinator to use configurable radius - RDEPUBChapterWindowSnapshot.from() accepts chapter array instead of fixed prev/next - Even numbers round up to odd (4→5), min 3, max 15 2. Configurable metadata parsing concurrency (metadataParsingConcurrency) - Default equals CPU core count - Parallel execution via OperationQueue in paginateMetadataOnly - Each worker creates independent builder instance - NSLock protects result aggregation 3. Per-chapter and total wall-clock timing instrumentation - Separated render vs I/O timing per chapter - Summary log with wallClockMs, renderTotalMs, writeTotalMs, avgRenderMs - Timing stored in RDEPUBReaderContext for test access 4. UI automation test infrastructure - Added --demo-window-size, --demo-concurrency, --demo-clear-cache launch args - DemoReaderState exposes windowSize, parseMs, parseConcurrency - ConfigurableWindowTests: 5 test cases for window size 3/5/15 - ConcurrentParsingTests: 4 test cases for concurrency 2/4 - MetadataParseBenchmarkTests: serial vs parallel benchmark 5. Bug fixes - Fixed page snap-back during background parsing (isUserInteracting check) - Reduced BookPageMap refresh frequency from 16 to 32 chapters - Moved waitForReadingInteractionToSettle outside operation loop 6. Design doc: dual-layer PageMap (estimated + precise mixed)
This commit is contained in:
@@ -107,6 +107,12 @@ public struct RDEPUBReaderConfiguration: Equatable {
|
||||
public var fixedLayoutSpreadMode: RDEPUBFixedLayoutSpreadMode
|
||||
/// 文本渲染引擎,默认使用 DTCoreText
|
||||
public var textRenderingEngine: RDEPUBTextRenderingEngine
|
||||
/// 章节按需加载窗口大小(总章节数,包含当前章),默认 3,范围 3...15,偶数自动向上取奇
|
||||
public var onDemandChapterWindowSize: Int
|
||||
/// 后台元数据解析并发数,默认为 CPU 核心数。
|
||||
/// 若 profiling 显示 renderTotalMs ≈ wallClockMs(渲染受限),维持核心数即可;
|
||||
/// 若 writeTotalMs 占比显著(I/O 等待),可试探 cpuCount * 1.25~1.5 以填充 I/O 等待间隙。
|
||||
public var metadataParsingConcurrency: Int
|
||||
|
||||
// MARK: 初始化
|
||||
|
||||
@@ -128,6 +134,8 @@ public struct RDEPUBReaderConfiguration: Equatable {
|
||||
/// - fixedLayoutFit: 固定布局适配模式
|
||||
/// - fixedLayoutSpreadMode: 固定布局跨页模式
|
||||
/// - textRenderingEngine: 文本渲染引擎
|
||||
/// - onDemandChapterWindowSize: 章节按需加载窗口大小(总章节数 3...15,偶数自动向上取奇)
|
||||
/// - metadataParsingConcurrency: 后台元数据解析并发数,默认 CPU 核心数
|
||||
public init(
|
||||
fontSize: CGFloat = 15,
|
||||
lineHeightMultiple: CGFloat = 1.6,
|
||||
@@ -146,7 +154,9 @@ public struct RDEPUBReaderConfiguration: Equatable {
|
||||
darkImageBlendRatio: CGFloat = 0.15,
|
||||
fixedLayoutFit: RDEPUBFixedLayoutFit = .page,
|
||||
fixedLayoutSpreadMode: RDEPUBFixedLayoutSpreadMode = .automatic,
|
||||
textRenderingEngine: RDEPUBTextRenderingEngine = .dtCoreText
|
||||
textRenderingEngine: RDEPUBTextRenderingEngine = .dtCoreText,
|
||||
onDemandChapterWindowSize: Int = 3,
|
||||
metadataParsingConcurrency: Int = ProcessInfo.processInfo.activeProcessorCount
|
||||
) {
|
||||
self.fontSize = fontSize
|
||||
self.lineHeightMultiple = lineHeightMultiple
|
||||
@@ -166,12 +176,25 @@ public struct RDEPUBReaderConfiguration: Equatable {
|
||||
self.fixedLayoutFit = fixedLayoutFit
|
||||
self.fixedLayoutSpreadMode = fixedLayoutSpreadMode
|
||||
self.textRenderingEngine = textRenderingEngine
|
||||
self.onDemandChapterWindowSize = Self.normalizedChapterWindowSize(onDemandChapterWindowSize)
|
||||
self.metadataParsingConcurrency = max(1, metadataParsingConcurrency)
|
||||
}
|
||||
|
||||
/// 默认配置实例,使用所有参数的默认值
|
||||
public static let `default` = RDEPUBReaderConfiguration()
|
||||
}
|
||||
|
||||
extension RDEPUBReaderConfiguration {
|
||||
static func normalizedChapterWindowSize(_ size: Int) -> Int {
|
||||
let clamped = max(3, min(15, size))
|
||||
return clamped % 2 == 0 ? clamped + 1 : clamped
|
||||
}
|
||||
|
||||
var chapterWindowRadius: Int {
|
||||
onDemandChapterWindowSize / 2
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - 配置转换
|
||||
|
||||
extension RDEPUBReaderConfiguration {
|
||||
|
||||
Reference in New Issue
Block a user