Skip to content

Instantly share code, notes, and snippets.

@Demon000
Created August 26, 2024 09:43
Show Gist options
  • Save Demon000/0f36b693fbdbc176a02f71dc4415aa50 to your computer and use it in GitHub Desktop.
Save Demon000/0f36b693fbdbc176a02f71dc4415aa50 to your computer and use it in GitHub Desktop.
Bash script profiling line by line
#!/usr/bin/env python3
import os
import sys
def parse_line(line):
parts = line.split('␞')
script_path = os.path.normpath(parts[1])
line_no = int(parts[2])
time = float(parts[3])
rest = parts[4]
return [script_path, line_no, time, rest]
def parse_profile_file(file_path):
data = {}
with open(file_path, 'r') as f:
last_line_data = None
line_data = None
for line in f:
if line.startswith('␝'):
if last_line_data is not None:
script_path, line_no, delta, rest = last_line_data
script_data = data.setdefault(script_path, {})
line_profile_data = script_data.setdefault(line_no, [0, 0, rest])
line_profile_data[0] += delta
line_profile_data[1] += 1
last_line_data = line_data
line_data = parse_line(line)
if last_line_data is not None:
last_line_data[2] = line_data[2] - last_line_data[2]
else:
line_data[-1] += line
return data
PROFILE_FILE_PATH = sys.argv[1]
profile_data = parse_profile_file(PROFILE_FILE_PATH)
print('Line number\tTotal time in seconds\tNumber of occurances\tFirst call')
for script_path, lines in profile_data.items():
print(script_path)
lines_time = list(lines.items())
lines_time.sort(key=lambda x: x[1], reverse=True)
for line, [time, calls, rest] in lines_time:
print(f'{line} {time:.16f} {calls} {rest}')
print()
PS4='␝␞$BASH_SOURCE␞$LINENO␞$EPOCHREALTIME␞'
exec 3>&2 2>/tmp/extract-files.log
set -x
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment