feat: integrate Google semantic search and branded desktop launcher
Core CI / core (ubuntu-latest) (push) Failing after 3m27s
Core CI / core (macos-latest) (push) Canceled after 0s
Core CI / core (windows-latest) (push) Canceled after 0s
Core CI / desktop (ubuntu-latest) (push) Successful in 5m45s
Core CI / desktop (macos-latest) (push) Canceled after 0s
Core CI / desktop (windows-latest) (push) Canceled after 0s
Core CI / core (ubuntu-latest) (push) Failing after 3m27s
Core CI / core (macos-latest) (push) Canceled after 0s
Core CI / core (windows-latest) (push) Canceled after 0s
Core CI / desktop (ubuntu-latest) (push) Successful in 5m45s
Core CI / desktop (macos-latest) (push) Canceled after 0s
Core CI / desktop (windows-latest) (push) Canceled after 0s
This commit is contained in:
1 parent
a90df15503
commit
caf6a2f82e
80 files changed
+14971
-837
No files matched your search
@@ -12,6 +12,7 @@ struct Measurements {
|
||||
samples: usize,
|
||||
p50_ms: f64,
|
||||
first_query_ms: f64,
|
||||
first_query_target_met: bool,
|
||||
p95_ms: f64,
|
||||
target_p95_ms: f64,
|
||||
target_met: bool,
|
||||
@@ -19,6 +20,12 @@ struct Measurements {
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Report {
|
||||
background_prepare_seconds: f64,
|
||||
reopened_background_prepare_seconds: f64,
|
||||
background_representative_queries: Vec<String>,
|
||||
prepared_frequency_count: usize,
|
||||
first_foreground_distinct_names: DistinctMeasurements,
|
||||
reopened_reader_first_names: DistinctMeasurements,
|
||||
fixture: &'static str,
|
||||
files: usize,
|
||||
documents: usize,
|
||||
@@ -33,6 +40,84 @@ struct Report {
|
||||
queries: Vec<Measurements>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct DistinctMeasurements {
|
||||
description: &'static str,
|
||||
includes_reader_open: bool,
|
||||
queries: Vec<String>,
|
||||
samples_ms: Vec<f64>,
|
||||
p50_ms: f64,
|
||||
p95_ms: f64,
|
||||
first_sample_ms: f64,
|
||||
first_sample_target_met: bool,
|
||||
maximum_ms: f64,
|
||||
samples_exceeding_target: usize,
|
||||
target_p95_ms: f64,
|
||||
target_met: bool,
|
||||
}
|
||||
|
||||
fn distinct_names(
|
||||
index: &SearchIndex,
|
||||
database: &std::path::Path,
|
||||
files: usize,
|
||||
reopen: bool,
|
||||
) -> Result<DistinctMeasurements> {
|
||||
let count = 20.min(files / 2);
|
||||
let mut queries = Vec::with_capacity(count);
|
||||
let mut samples_ms = Vec::with_capacity(count);
|
||||
for sample in 0..count {
|
||||
// Two disjoint deterministic sets spread across the entire corpus.
|
||||
// Neither set repeats the four-case exact filename at files-1.
|
||||
let number = sample * (files - 2) / count + usize::from(reopen);
|
||||
let query = format!("invoice_{number:07}.txt");
|
||||
let start = Instant::now();
|
||||
let results = if reopen {
|
||||
SearchIndex::open(database)?.search(&query, 20)?
|
||||
} else {
|
||||
index.search(&query, 20)?
|
||||
};
|
||||
let elapsed = start.elapsed().as_secs_f64() * 1000.0;
|
||||
let first = results
|
||||
.first()
|
||||
.context("distinct exact query returned no results")?;
|
||||
if first.filename != query || first.match_kind != "exact_filename" {
|
||||
bail!("distinct query lost exact filename priority");
|
||||
}
|
||||
queries.push(query);
|
||||
samples_ms.push(elapsed);
|
||||
}
|
||||
let mut sorted = samples_ms.clone();
|
||||
sorted.sort_by(f64::total_cmp);
|
||||
let percentile = |fraction: f64| {
|
||||
sorted[((sorted.len() as f64 * fraction).ceil() as usize).saturating_sub(1)]
|
||||
};
|
||||
let p95_ms = percentile(0.95);
|
||||
eprintln!(
|
||||
"{} distinct first filename queries (reopened={reopen}): p95 {p95_ms:.3} ms",
|
||||
count
|
||||
);
|
||||
let first_sample_ms = samples_ms[0];
|
||||
let samples_exceeding_target = samples_ms.iter().filter(|sample| **sample >= 50.0).count();
|
||||
Ok(DistinctMeasurements {
|
||||
description: if reopen {
|
||||
"each never-repeated filename on a newly opened reader, persisted statistics, no prewarm; includes open+search"
|
||||
} else {
|
||||
"distinct foreground filenames; no benchmark query warmups; production background representative queries may overlap"
|
||||
},
|
||||
includes_reader_open: reopen,
|
||||
queries,
|
||||
samples_ms,
|
||||
p50_ms: percentile(0.5),
|
||||
p95_ms,
|
||||
first_sample_ms,
|
||||
first_sample_target_met: first_sample_ms < 50.0,
|
||||
maximum_ms: sorted[sorted.len() - 1],
|
||||
samples_exceeding_target,
|
||||
target_p95_ms: 50.0,
|
||||
target_met: p95_ms < 50.0,
|
||||
})
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let arguments = env::args().skip(1).collect::<Vec<_>>();
|
||||
let mut files = 10_000usize;
|
||||
@@ -53,13 +138,12 @@ fn main() -> Result<()> {
|
||||
option => bail!("unknown argument {option}"),
|
||||
}
|
||||
}
|
||||
if files == 0
|
||||
|| files > 2_000_000
|
||||
if !(2..=2_000_000).contains(&files)
|
||||
|| documents == 0
|
||||
|| documents > files
|
||||
|| !(5..=1000).contains(&samples)
|
||||
{
|
||||
bail!("files must be1..2000000, documents1..files, samples5..1000");
|
||||
bail!("files must be2..2000000, documents1..files, samples5..1000");
|
||||
}
|
||||
if database.exists() && !reuse {
|
||||
bail!(
|
||||
@@ -135,7 +219,41 @@ fn main() -> Result<()> {
|
||||
start.elapsed().as_secs_f64()
|
||||
};
|
||||
let database_bytes = fs::metadata(&database)?.len();
|
||||
let index = SearchIndex::open(&database)?;
|
||||
let mut index = SearchIndex::open(&database)?;
|
||||
let connection = Connection::open(&database)?;
|
||||
let mut statement=connection.prepare("SELECT filename FROM files WHERE id=(SELECT min(id) FROM files) OR id=(SELECT max(id) FROM files)")?;
|
||||
let mut background_representative_queries = statement
|
||||
.query_map([], |row| row.get::<_, String>(0))?
|
||||
.collect::<rusqlite::Result<Vec<_>>>()?;
|
||||
let words = background_representative_queries
|
||||
.iter()
|
||||
.flat_map(|name| {
|
||||
name.split(|character: char| !character.is_alphabetic())
|
||||
.filter(|word| word.chars().count() >= 3)
|
||||
.take(3)
|
||||
})
|
||||
.map(str::to_owned)
|
||||
.collect::<std::collections::BTreeSet<_>>();
|
||||
background_representative_queries.extend(words);
|
||||
let text: String = connection.query_row(
|
||||
"SELECT substr(content,1,256) FROM files WHERE content!='' ORDER BY id LIMIT 1",
|
||||
[],
|
||||
|row| row.get(0),
|
||||
)?;
|
||||
background_representative_queries.extend(
|
||||
text.split_whitespace()
|
||||
.filter(|term| term.chars().all(char::is_alphanumeric))
|
||||
.take(3)
|
||||
.map(str::to_owned),
|
||||
);
|
||||
drop(statement);
|
||||
drop(connection);
|
||||
let preparation = Instant::now();
|
||||
let prepared_frequency_count = index.prewarm()?;
|
||||
let background_prepare_seconds = preparation.elapsed().as_secs_f64();
|
||||
// Measure user-like first inputs before the old repeated-query cases.
|
||||
let first_foreground_distinct_names = distinct_names(&index, &database, files, false)?;
|
||||
let reopened_reader_first_names = distinct_names(&index, &database, files, true)?;
|
||||
let exact = format!("invoice_{:07}.txt", files - 1);
|
||||
let unique_content = format!("marker{:07}", documents - 1);
|
||||
let cases = [
|
||||
@@ -175,12 +293,25 @@ fn main() -> Result<()> {
|
||||
samples,
|
||||
p50_ms: percentile(0.5),
|
||||
first_query_ms,
|
||||
first_query_target_met: first_query_ms < target,
|
||||
p95_ms,
|
||||
target_p95_ms: target,
|
||||
target_met: p95_ms < target,
|
||||
});
|
||||
}
|
||||
// Measure restart preparation after foreground samples, so a second
|
||||
// prewarm cannot secretly improve the first-input measurements above.
|
||||
let mut restarted = SearchIndex::open(&database)?;
|
||||
let restart_start = Instant::now();
|
||||
restarted.prewarm()?;
|
||||
let reopened_background_prepare_seconds = restart_start.elapsed().as_secs_f64();
|
||||
let report = Report {
|
||||
background_prepare_seconds,
|
||||
reopened_background_prepare_seconds,
|
||||
background_representative_queries,
|
||||
prepared_frequency_count,
|
||||
first_foreground_distinct_names,
|
||||
reopened_reader_first_names,
|
||||
fixture:
|
||||
"synthetic SQLite metadata and text; no filesystem extraction or semantic inference",
|
||||
files,
|
||||
|
||||
Reference in new issue
Block a user