241 lines
5.5 KiB
Nim
241 lines
5.5 KiB
Nim
## Example: Profile Resolver Operations
|
|
##
|
|
## This example demonstrates how to profile actual resolver operations
|
|
## to identify performance bottlenecks and optimization opportunities.
|
|
|
|
import ../src/nip/resolver/profiler
|
|
import ../src/nip/resolver/types
|
|
import ../src/nip/resolver/variant_unification
|
|
import ../src/nip/resolver/graph_builder
|
|
import ../src/nip/resolver/topological_sort
|
|
import ../src/nip/resolver/optimizations
|
|
import times
|
|
import strformat
|
|
|
|
# ============================================================================
|
|
# Example Resolver Operations
|
|
# ============================================================================
|
|
|
|
proc simulateVariantUnification() =
|
|
## Simulate variant unification operations
|
|
|
|
let opId = startOperation(VariantUnification, "unify-nginx")
|
|
|
|
let v1 = VariantDemand(
|
|
useFlags: @["ssl", "http2"],
|
|
libc: "musl",
|
|
allocator: "jemalloc",
|
|
targetArch: "x86_64",
|
|
buildFlags: @[]
|
|
)
|
|
|
|
let v2 = VariantDemand(
|
|
useFlags: @["brotli", "gzip"],
|
|
libc: "musl",
|
|
allocator: "jemalloc",
|
|
targetArch: "x86_64",
|
|
buildFlags: @[]
|
|
)
|
|
|
|
let result = unifyVariants(@[v1, v2])
|
|
discard result
|
|
|
|
endOperation(opId)
|
|
|
|
proc simulateGraphConstruction() =
|
|
## Simulate dependency graph construction
|
|
|
|
let opId = startOperation(GraphConstruction, "build-graph")
|
|
|
|
var graph = DependencyGraph(
|
|
nodes: @[],
|
|
edges: @[]
|
|
)
|
|
|
|
# Add some nodes
|
|
for i in 0..<50:
|
|
let node = PackageId(
|
|
name: fmt"package-{i}",
|
|
version: "1.0.0",
|
|
variant: "default"
|
|
)
|
|
graph.nodes.add(node)
|
|
|
|
# Add some edges
|
|
for i in 0..<40:
|
|
let edge = DependencyEdge(
|
|
from: graph.nodes[i],
|
|
to: graph.nodes[i + 1],
|
|
kind: Required
|
|
)
|
|
graph.edges.add(edge)
|
|
|
|
endOperation(opId)
|
|
|
|
proc simulateTopologicalSort() =
|
|
## Simulate topological sort
|
|
|
|
let opId = startOperation(TopologicalSort, "topo-sort")
|
|
|
|
var graph = DependencyGraph(
|
|
nodes: @[],
|
|
edges: @[]
|
|
)
|
|
|
|
# Create a simple chain
|
|
for i in 0..<30:
|
|
let node = PackageId(
|
|
name: fmt"package-{i}",
|
|
version: "1.0.0",
|
|
variant: "default"
|
|
)
|
|
graph.nodes.add(node)
|
|
|
|
for i in 0..<29:
|
|
let edge = DependencyEdge(
|
|
from: graph.nodes[i],
|
|
to: graph.nodes[i + 1],
|
|
kind: Required
|
|
)
|
|
graph.edges.add(edge)
|
|
|
|
let sorted = topologicalSort(graph)
|
|
discard sorted
|
|
|
|
endOperation(opId)
|
|
|
|
proc simulateConflictDetection() =
|
|
## Simulate conflict detection
|
|
|
|
let opId = startOperation(ConflictDetection, "detect-conflicts")
|
|
|
|
let packages = @[
|
|
PackageId(name: "nginx", version: "1.24.0", variant: "default"),
|
|
PackageId(name: "nginx", version: "1.25.0", variant: "default"),
|
|
PackageId(name: "apache", version: "2.4.0", variant: "default")
|
|
]
|
|
|
|
let index = buildPackageIndex(packages)
|
|
let conflicts = detectVersionConflictsFast(index)
|
|
discard conflicts
|
|
|
|
endOperation(opId)
|
|
|
|
proc simulateHashCalculation() =
|
|
## Simulate hash calculations
|
|
|
|
let opId = startOperation(HashCalculation, "calculate-hashes")
|
|
|
|
let cache = newHashCache()
|
|
|
|
for i in 0..<100:
|
|
let hash = cache.getCachedHash(fmt"key-{i}", proc(): string =
|
|
# Simulate expensive hash calculation
|
|
var result = ""
|
|
for j in 0..<1000:
|
|
result.add($j)
|
|
return result
|
|
)
|
|
discard hash
|
|
|
|
endOperation(opId)
|
|
|
|
proc simulateBuildSynthesis() =
|
|
## Simulate build synthesis
|
|
|
|
let opId = startOperation(BuildSynthesis, "synthesize-build")
|
|
|
|
let demand = VariantDemand(
|
|
useFlags: @["ssl", "http2", "brotli"],
|
|
libc: "musl",
|
|
allocator: "jemalloc",
|
|
targetArch: "x86_64",
|
|
buildFlags: @["-O2", "-march=native"]
|
|
)
|
|
|
|
# Simulate build hash calculation
|
|
var components: seq[string] = @[]
|
|
components.add("source-hash")
|
|
components.add(demand.libc)
|
|
components.add(demand.allocator)
|
|
for flag in demand.useFlags:
|
|
components.add(flag)
|
|
|
|
let buildHash = components.join("|")
|
|
discard buildHash
|
|
|
|
endOperation(opId)
|
|
|
|
# ============================================================================
|
|
# Main Profiling Example
|
|
# ============================================================================
|
|
|
|
proc main() =
|
|
echo ""
|
|
echo "=" .repeat(80)
|
|
echo "PROFILING RESOLVER OPERATIONS"
|
|
echo "=" .repeat(80)
|
|
echo ""
|
|
|
|
# Enable profiler
|
|
enableProfiler()
|
|
|
|
echo "Running resolver operations..."
|
|
echo ""
|
|
|
|
# Simulate typical resolver workflow
|
|
for iteration in 0..<10:
|
|
echo fmt"Iteration {iteration + 1}/10"
|
|
|
|
# Variant unification (frequent operation)
|
|
for i in 0..<20:
|
|
simulateVariantUnification()
|
|
|
|
# Graph construction (moderate frequency)
|
|
for i in 0..<5:
|
|
simulateGraphConstruction()
|
|
|
|
# Topological sort (moderate frequency)
|
|
for i in 0..<5:
|
|
simulateTopologicalSort()
|
|
|
|
# Conflict detection (less frequent)
|
|
for i in 0..<3:
|
|
simulateConflictDetection()
|
|
|
|
# Hash calculation (frequent)
|
|
for i in 0..<10:
|
|
simulateHashCalculation()
|
|
|
|
# Build synthesis (less frequent)
|
|
for i in 0..<2:
|
|
simulateBuildSynthesis()
|
|
|
|
# Disable profiler
|
|
disableProfiler()
|
|
|
|
echo ""
|
|
echo "Profiling complete!"
|
|
echo ""
|
|
|
|
# Print report
|
|
printReport()
|
|
printOptimizationRecommendations()
|
|
|
|
# Export to CSV
|
|
exportToCSV("resolver_profiling.csv")
|
|
exportDetailedToCSV("resolver_profiling_detailed.csv")
|
|
|
|
echo ""
|
|
echo "=" .repeat(80)
|
|
echo "PROFILING COMPLETE"
|
|
echo "=" .repeat(80)
|
|
echo ""
|
|
echo "Results exported to:"
|
|
echo " - resolver_profiling.csv (summary)"
|
|
echo " - resolver_profiling_detailed.csv (detailed timings)"
|
|
echo ""
|
|
|
|
when isMainModule:
|
|
main()
|