Skip to content

Commit

Permalink
perf: avoid quadratic behavior when combining line coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
nedbat committed May 27, 2024
1 parent d3caf53 commit 390cb97
Showing 1 changed file with 27 additions and 26 deletions.
53 changes: 27 additions & 26 deletions coverage/sqldata.py
Original file line number Diff line number Diff line change
Expand Up @@ -767,45 +767,46 @@ def update(self, other_data: CoverageData, aliases: PathAliases | None = None) -
# Prepare arc and line rows to be inserted by converting the file
# and context strings with integer ids. Then use the efficient
# `executemany()` to insert all rows at once.
arc_rows = (
(file_ids[file], context_ids[context], fromno, tono)
for file, context, fromno, tono in arcs
)

# Get line data.
with con.execute(
"select file.path, context.context, line_bits.numbits " +
"from line_bits " +
"inner join file on file.id = line_bits.file_id " +
"inner join context on context.id = line_bits.context_id",
) as cur:
for path, context, numbits in cur:
key = (aliases.map(path), context)
if key in lines:
numbits = numbits_union(lines[key], numbits)
lines[key] = numbits
if lines:
self._choose_lines_or_arcs(lines=True)

with con.execute(
"select file.path, context.context, line_bits.numbits " +
"from line_bits " +
"inner join file on file.id = line_bits.file_id " +
"inner join context on context.id = line_bits.context_id",
) as cur:
for path, context, numbits in cur:
key = (aliases.map(path), context)
if key in lines:
lines[key] = numbits_union(lines[key], numbits)

con.executemany_void(
"insert or replace into line_bits " +
"(file_id, context_id, numbits) values (?, ?, ?)",
[
(file_ids[file], context_ids[context], numbits)
for (file, context), numbits in lines.items()
],
)

if arcs:
self._choose_lines_or_arcs(arcs=True)

arc_rows = (
(file_ids[file], context_ids[context], fromno, tono)
for file, context, fromno, tono in arcs
)

# Write the combined data.
con.executemany_void(
"insert or ignore into arc " +
"(file_id, context_id, fromno, tono) values (?, ?, ?, ?)",
arc_rows,
)

if lines:
self._choose_lines_or_arcs(lines=True)
con.execute_void("delete from line_bits")
con.executemany_void(
"insert into line_bits " +
"(file_id, context_id, numbits) values (?, ?, ?)",
[
(file_ids[file], context_ids[context], numbits)
for (file, context), numbits in lines.items()
],
)
con.executemany_void(
"insert or ignore into tracer (file_id, tracer) values (?, ?)",
((file_ids[filename], tracer) for filename, tracer in tracer_map.items()),
Expand Down

0 comments on commit 390cb97

Please sign in to comment.