mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-05 01:50:27 +08:00
- Add `association_tree` module with components for building and processing call association trees using LSP call hierarchy capabilities. - Introduce `AssociationTreeBuilder` for constructing call trees from seed locations with depth-first expansion. - Create data structures: `TreeNode`, `CallTree`, and `UniqueNode` for representing nodes and relationships in the call tree. - Implement `ResultDeduplicator` to extract unique nodes from call trees and assign relevance scores based on depth, frequency, and kind. - Add unit tests for `AssociationTreeBuilder` and `ResultDeduplicator` to ensure functionality and correctness.
111 lines
3.0 KiB
Python
111 lines
3.0 KiB
Python
"""Simple search method comparison using CLI commands.
|
|
|
|
Compares:
|
|
1. FTS (Full-Text Search)
|
|
2. Semantic (Dense + Rerank)
|
|
3. Hybrid (Future: FTS + Semantic fusion)
|
|
|
|
Usage:
|
|
python examples/simple_search_comparison.py
|
|
"""
|
|
|
|
import subprocess
|
|
import time
|
|
import json
|
|
from pathlib import Path
|
|
|
|
def run_search(query: str, method: str, limit: int = 20) -> tuple[list, float]:
|
|
"""Run search via CLI and measure time."""
|
|
cmd = [
|
|
"python", "-m", "codexlens", "search",
|
|
query,
|
|
"--method", method,
|
|
"--limit", str(limit),
|
|
"--json",
|
|
"-p", "."
|
|
]
|
|
|
|
start = time.perf_counter()
|
|
result = subprocess.run(
|
|
cmd,
|
|
cwd=str(Path("D:/Claude_dms3/codex-lens/src")),
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
elapsed = time.perf_counter() - start
|
|
|
|
if result.returncode != 0:
|
|
print(f"Error running {method} search:")
|
|
print(result.stderr)
|
|
return [], elapsed
|
|
|
|
try:
|
|
data = json.loads(result.stdout)
|
|
return data.get("results", []), elapsed
|
|
except json.JSONDecodeError:
|
|
print(f"Failed to parse JSON output for {method}")
|
|
return [], elapsed
|
|
|
|
|
|
def print_comparison(query: str):
|
|
"""Print comparison for a single query."""
|
|
print(f"\n{'='*80}")
|
|
print(f"Query: {query}")
|
|
print(f"{'='*80}\n")
|
|
|
|
# Method 1: FTS
|
|
print("Method 1: FTS (Full-Text Search)")
|
|
results_fts, time_fts = run_search(query, "fts", 20)
|
|
print(f" Time: {time_fts*1000:.2f}ms")
|
|
print(f" Results: {len(results_fts)}")
|
|
if results_fts:
|
|
print(f" Top 3:")
|
|
for i, r in enumerate(results_fts[:3], 1):
|
|
path = r.get("path", "").replace("D:\\Claude_dms3\\codex-lens\\src\\", "")
|
|
score = r.get("score", 0)
|
|
print(f" {i}. [{score:.4f}] {path}")
|
|
print()
|
|
|
|
# Method 2: Semantic (Dense + Rerank)
|
|
print("Method 2: Semantic (Dense + Rerank)")
|
|
results_semantic, time_semantic = run_search(query, "dense_rerank", 20)
|
|
print(f" Time: {time_semantic*1000:.2f}ms")
|
|
print(f" Results: {len(results_semantic)}")
|
|
if results_semantic:
|
|
print(f" Top 3:")
|
|
for i, r in enumerate(results_semantic[:3], 1):
|
|
path = r.get("path", "").replace("D:\\Claude_dms3\\codex-lens\\src\\", "")
|
|
score = r.get("score", 0)
|
|
print(f" {i}. [{score:.4f}] {path}")
|
|
print()
|
|
|
|
# Summary
|
|
print(f"Summary:")
|
|
print(f" FTS: {time_fts*1000:8.2f}ms {len(results_fts):3d} results")
|
|
print(f" Semantic: {time_semantic*1000:8.2f}ms {len(results_semantic):3d} results")
|
|
print(f" Speedup: {time_semantic/time_fts:6.2f}x (FTS faster)")
|
|
|
|
|
|
def main():
|
|
"""Main comparison entry point."""
|
|
queries = [
|
|
"vector search",
|
|
"LSP call hierarchy",
|
|
"search ranking",
|
|
"index building",
|
|
]
|
|
|
|
print("Search Method Comparison")
|
|
print("=" * 80)
|
|
|
|
for query in queries:
|
|
print_comparison(query)
|
|
|
|
print(f"\n{'='*80}")
|
|
print("Comparison complete")
|
|
print(f"{'='*80}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|