Skip to content

Commit

Permalink
Fixed up benchmark. Added dump method to sql.py
Browse files Browse the repository at this point in the history
  • Loading branch information
fzakaria committed Oct 3, 2023
1 parent 358dc4b commit 572c7e7
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 29 deletions.
31 changes: 19 additions & 12 deletions benchmarks/graph_symbol_size_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,27 @@

# Raw data
data = {
"Number of Functions": [10**exponent for exponent in range(1, 6)],
"Number of Functions": [10, 100, 1000, 10000, 100000],
"readelf": [
0.005350531006115489,
0.005340991003322415,
0.005842811006004922,
0.01410250501066912,
0.09029568900587037,
0.0052862250013276935,
0.005087099008960649,
0.005879847012693062,
0.01378464701701887,
0.09143825399223715,
],
"sqlelf": [
0.02874817499832716,
0.07305189099861309,
0.53968190800515,
5.312782863009488,
51.02671549099614,
0.026774031983222812,
0.07022259500809014,
0.5325515430013184,
5.426244292000774,
51.41806371998973,
],
"sqlelf-memoized": [
0.0006310690077953041,
0.0012372269993647933,
0.0005934310029260814,
0.0008586860203649849,
0.0030715609900653362,
],
}

Expand All @@ -30,7 +37,7 @@
df_melted = pd.melt(
df,
id_vars=["Number of Functions"],
value_vars=["readelf", "sqlelf"],
value_vars=["readelf", "sqlelf", "sqlelf-memoized"],
var_name="Category",
value_name="Value",
)
Expand Down
64 changes: 47 additions & 17 deletions benchmarks/symbol_size_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,24 @@
import timeit
import tempfile
import subprocess
from pathlib import Path
from sqlelf import sql, elf
import pprint
import sqlite3
import time


def create_executable_file(file_name: str, num_functions: int) -> str:
def create_executable_file(
file: tempfile.NamedTemporaryFile, num_functions: int
) -> str:
"""Create an ELF executable file with a given number of functions"""
functions = ""
for i in range(num_functions):
functions += f"""void function_{i}() {{ printf("Hello World {i}"); }}\n"""
functions = [
f"""void function_{i}() {{ printf("Hello World {i}"); }}\n"""
for i in range(num_functions)
]
functions_str = "".join(functions)
content = f"""
#include <stdio.h>
{functions}
{functions_str}
int main() {{ printf("Hello World!"); return 0; }}
"""
file.write(content)
Expand Down Expand Up @@ -43,24 +48,49 @@ def sqlelf_benchmark(binary_name: str, num_functions: int) -> None:
assert count >= num_functions


def sqlelf_memoized_benchmark(sqlite_database: str, num_functions: int) -> None:
with sqlite3.connect(sqlite_database) as con:
result = list(con.execute("SELECT COUNT(*) as 'count' FROM ELF_SYMBOLS"))
count = result[0][0]
assert count >= num_functions


data = {"Number of Functions": [], "sqlelf": [], "sqlelf-memoized": [], "readelf": []}

for exponent in range(1, 6):
num_functions = 10**exponent
data["Number of Functions"].append(num_functions)

print(f"Number of functions: {num_functions}")
# create the executable
with tempfile.NamedTemporaryFile(mode="w") as file:
file_name = file.name
binary_file = create_executable_file(file_name, num_functions)
print(
"readelf benchmark: {}".format(
timeit.timeit(
lambda: readelf_benchmark(binary_file, num_functions), number=1
)
binary_file = create_executable_file(file, num_functions)
data["readelf"].append(
min(
timeit.Timer(
lambda: readelf_benchmark(binary_file, num_functions)
).repeat(repeat=10, number=1)
)
)
data["sqlelf"].append(
timeit.timeit(
lambda: sqlelf_benchmark(binary_file, num_functions), number=1
)
)
print(
"sqlelf benchmark: {}".format(
timeit.timeit(
lambda: sqlelf_benchmark(binary_file, num_functions), number=1
)

sql_engine = sql.make_sql_engine(
[binary_file], cache_flags=elf.CacheFlag.SYMBOLS
)

sqlite_database = tempfile.NamedTemporaryFile().name
sql_engine.dump(sqlite_database)
data["sqlelf-memoized"].append(
min(
timeit.Timer(
lambda: sqlelf_memoized_benchmark(sqlite_database, num_functions),
).repeat(repeat=10, number=1)
)
)

pprint.pprint(data)
11 changes: 11 additions & 0 deletions sqlelf/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ def shell(self, stdin: TextIO = sys.stdin) -> apsw.shell.Shell:
shell.command_prompt(["sqlelf> "]) # type: ignore[no-untyped-call]
return shell

def dump(self, file_name: str) -> None:
"""Dump the database to a file"""
out_connection = apsw.Connection(file_name)
backup = out_connection.backup("main", self.connection, "main")
try:
while not backup.done:
backup.step()
finally:
backup.finish()
out_connection.close()

def execute_raw(
self, sql: str, bindings: Optional["apsw.Bindings"] = None
) -> apsw.Cursor:
Expand Down

0 comments on commit 572c7e7

Please sign in to comment.