Improve performance to limit file reads when generating fuzzed values.
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 45/100
- Tipo de issue
- Refactorización
- Claridad
- Bien especificado
- Estado de actividad
- Estancado
- Stack tecnológico
- python
- Área
- performance
Línea de trabajo
Start in values.py at _fuzzdb_get_strings, _fuzzdb_integers, and _limit_helper, then review the attached diff against commit a4fd0936ae501dba0fc89d3af4ead8ef3aaad1d1. Exercise the protobuf workload described in protofuzz.py and compare profiling results. Done means repeated fuzzed-value generation avoids rereading the fuzzdb files while preserving max_len and limit behavior.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
There is a pretty obvious performance bottleneck. In the function _fuzzdb_get_strings and in the function _fuzzdb_integers the function reads the entire fuzzdb files on every call.
for subdir in os.listdir(_get_fuzzdb_path()):
if subdir in ignored:
continue
subdir_abs_path = _get_fuzzdb_path() / Path(subdir)
try:
listing = os.listdir(subdir_abs_path)
except NotADirectoryError:
continue
for filename in listing:
if not filename.endswith(".txt"):
continue
subdir_abs_path_filename = subdir_abs_path / Path(filename)
with open(subdir_abs_path_filename, "rb") as source:
for line in source:
string = line.decode("utf-8").strip()
if not string or string.startswith("#"):
continue
if max_len != 0 and len(line) > max_len:
continue
yield string
This causes a pretty obvious performance bottleneck because the file gets read on every call. Instead of reading the file every time a much better strategy would be to put all of the values in to a list and then just return the stuff from that list from ram instead of reading it from the disk constantly.
strings = []
def _fuzzdb_get_strings(max_len: int = 0) -> Generator:
"""Return strings from fuzzdb."""
if strings == []:
ignored = ["integer-overflow"]
for subdir in os.listdir(_get_fuzzdb_path()):
if subdir in ignored:
continue
subdir_abs_path = _get_fuzzdb_path() / Path(subdir)
try:
listing = os.listdir(subdir_abs_path)
except NotADirectoryError:
continue
for filename in listing:
if not filename.endswith(".txt"):
continue
subdir_abs_path_filename = subdir_abs_path / Path(filename)
with open(subdir_abs_path_filename, "rb") as source:
for line in source:
string = line.decode("utf-8").strip()
if not string or string.startswith("#"):
continue
if max_len != 0 and len(line) > max_len:
continue
strings.append(string)
yield string
else:
for string in strings:
yield string
We can also obviously do the same for the integers:
integers = []
def _fuzzdb_integers(limit: int = 0) -> Generator:
"""Return integers from fuzzdb."""
if integers == []:
path = _get_fuzzdb_path() / Path("integer-overflow/integer-overflows.txt")
with open(path, "rb") as stream:
for line in _limit_helper(stream, limit):
integer = int(line.decode("utf-8"), 0)
integers.append(integer)
yield integer
else:
for integer in integers:
yield integer
When parsing around four thousand protobuf messages and then mutating them originally the cProfile was this:
['60786110', '50.667', '0.000', '100.909', '0.000', 'values.py:90(_fuzzdb_get_strings)']
['60973618/60973382', '15.971', '0.000', '116.882', '0.000', 'values.py:72(_limit_helper)']
['62370202', '10.454', '0.000', '10.454', '0.000', '{method', "'decode'", 'of', "'bytes'", 'objects}']
['60981956', '8.501', '0.000', '8.501', '0.000', '{method', "'startswith'", 'of', "'str'", 'objects}']
the second column is total time spent in the function.
after the optimization it is now this:
['60790067/60790036', '12.243', '0.000', '17.458', '0.000', 'values.py:69(_limit_helper)']
['60786110', '5.203', '0.000', '5.215', '0.000', 'values.py:97(_fuzzdb_get_strings)']
['4630', '4.368', '0.001', '20.797', '0.004', 'protofuzz.py:48(_string_generator)']
['265', '0.984', '0.004', '2.028', '0.008', 'protofuzz.py:55(<listcomp>)']
['371565/34403', '0.318', '0.000', '0.875', '0.000', 'gen.py:188(step_generator)']
['48027', '0.286', '0.000', '0.482', '0.000', 'python_message.py:469(init)']
So just by making this simple optimization I have cut down the processing time by atleast in 45 seconds easily.
I have attached a .zip file which contains a .diff file which implements the stuff. Apply it to the a4fd0936ae501dba0fc89d3af4ead8ef3aaad1d1 commit and you are done.
stuff.zip
- Lenguaje dominante
- Python
- Estrellas
- 288
- Forks
- 36
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de trailofbits/protofuzz
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 48/100
trailofbits/protofuzz#91 ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
trailofbits/protofuzz#57 ·
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 25/100
trailofbits/protofuzz#13 · 1 comentario ·
-
Dificultad 4/5 3-5 días Aptitud para principiantes 42/100
trailofbits/protofuzz#11 ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
trailofbits/protofuzz#7 · 1 comentario · 1 reacción ·
Todos los issues de trailofbits/protofuzz
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día
-
Claiming namespace `thejakia1`Abiertonamespace operations
Dificultad 1/5 Menos de una hora Aptitud para principiantes 65/100
EclipseFdn/open-vsx.org#15057 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
FinanceFlash/unvibecode#349 ·
-
Mission statement: why this is free, in the README, Why This Exists and the wiki HomePosiblemente ocupada @ChiefGyk3D la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
ChiefGyk3D/Clouds-Against-Humanity#348 ·
Los mantenedores suelen responder en 1 día
-
[Perf] Default --vllm-watermark 0.05 for rollouts (hybrid models re-preempt under KV pressure)Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
vllm-project/vime#508 ·
Los mantenedores suelen responder en 4 días