0
# Profile Data Model
1
2
Core classes representing profiler data structures including profiles, functions, calls, and cycles. These classes provide the foundation for all profiler data manipulation and analysis operations in gprof2dot.
3
4
## Capabilities
5
6
### Profile Container
7
8
The main container class that holds the entire profile data structure, including all functions, calls, and detected cycles.
9
10
```python { .api }
11
class Profile:
12
def __init__(self):
13
"""Initialize a new empty profile."""
14
15
def add_function(self, function):
16
"""
17
Add a function to the profile.
18
19
Args:
20
function (Function): Function object to add
21
"""
22
23
def add_cycle(self, cycle):
24
"""
25
Add a cycle to the profile.
26
27
Args:
28
cycle (Cycle): Cycle object to add
29
"""
30
31
def validate(self):
32
"""Validate the profile data structure for consistency."""
33
34
35
def prune(self, node_thres, edge_thres, paths, color_nodes_by_selftime):
36
"""
37
Remove nodes and edges below specified thresholds.
38
39
Args:
40
node_thres (float): Minimum node weight threshold (0.0-1.0)
41
edge_thres (float): Minimum edge weight threshold (0.0-1.0)
42
paths: Path constraints
43
color_nodes_by_selftime (bool): Color nodes by self time
44
"""
45
46
47
def dump(self):
48
"""Print debug representation of the profile."""
49
50
def find_cycles(self):
51
"""
52
Find cycles using Tarjan's strongly connected components algorithm.
53
54
Identifies mutually recursive function groups and creates Cycle objects
55
containing them. Updates self.cycles with discovered cycles.
56
"""
57
58
def prune_root(self, roots, depth=-1):
59
"""
60
Prune call graph to show only descendants of specified root functions.
61
62
Args:
63
roots: Collection of root function IDs
64
depth (int): Maximum traversal depth (-1 for unlimited)
65
"""
66
67
def prune_leaf(self, leafs, depth=-1):
68
"""
69
Prune call graph to show only ancestors of specified leaf functions.
70
71
Args:
72
leafs: Collection of leaf function IDs
73
depth (int): Maximum traversal depth (-1 for unlimited)
74
"""
75
76
def getFunctionIds(self, funcName):
77
"""
78
Get function IDs matching a glob pattern.
79
80
Args:
81
funcName (str): Glob pattern for function names
82
83
Returns:
84
list: List of matching function IDs
85
"""
86
87
def getFunctionId(self, funcName):
88
"""
89
Get single function ID matching a name pattern.
90
91
Args:
92
funcName (str): Function name pattern
93
94
Returns:
95
Function ID or None if not found
96
"""
97
```
98
99
### Function Representation
100
101
Represents individual functions in the profile with their associated call relationships and performance metrics.
102
103
```python { .api }
104
class Function:
105
def __init__(self, id, name):
106
"""
107
Initialize a new function.
108
109
Args:
110
id: Unique identifier
111
name (str): Function name
112
"""
113
114
def add_call(self, call):
115
"""
116
Add a call relationship to another function.
117
118
Args:
119
call (Call): Call object to add
120
"""
121
122
def get_call(self, callee_id):
123
"""
124
Get an existing call relationship.
125
126
Args:
127
callee_id: ID of the called function
128
129
Returns:
130
Call: The call object, or None if not found
131
"""
132
133
134
def dump(self):
135
"""Print debug representation of the function."""
136
137
def stripped_name(self):
138
"""
139
Remove extraneous information from C++ demangled function names.
140
141
Strips template parameters, function arguments, and const qualifiers
142
to create cleaner display names for visualization.
143
144
Returns:
145
str: Cleaned function name
146
"""
147
```
148
149
### Call Relationships
150
151
Represents call relationships between functions, including performance metrics for each call edge.
152
153
```python { .api }
154
class Call:
155
def __init__(self, callee_id):
156
"""
157
Initialize a new call relationship.
158
159
Args:
160
callee_id: ID of the called function
161
162
Note: Also initializes ratio and weight attributes to None.
163
"""
164
165
def dump(self):
166
"""Print debug representation of the call."""
167
```
168
169
### Cycle Detection
170
171
Represents groups of mutually recursive functions that form cycles in the call graph.
172
173
```python { .api }
174
class Cycle:
175
def __init__(self):
176
"""
177
Initialize a new cycle.
178
179
Note: Cycles don't have IDs or names, they are containers for recursive function groups.
180
"""
181
182
def add_function(self, function):
183
"""
184
Add a function to this cycle.
185
186
Args:
187
function (Function): Function that is part of the cycle
188
"""
189
```
190
191
### Base Object Class
192
193
Base class for all profile objects that can store event data (functions, calls, cycles).
194
195
```python { .api }
196
class Object:
197
def __init__(self, events=None):
198
"""
199
Initialize object with optional events dictionary.
200
201
Args:
202
events (dict, optional): Event data dictionary
203
"""
204
205
def __hash__(self):
206
"""Return hash based on object identity."""
207
208
def __eq__(self, other):
209
"""Check equality based on object identity."""
210
211
def __lt__(self, other):
212
"""Less-than comparison based on object ID."""
213
214
def __getitem__(self, event):
215
"""
216
Get the value for a specific event type.
217
218
Args:
219
event (Event): Event type to retrieve
220
221
Returns:
222
Value for the event, or raises UndefinedEvent
223
"""
224
225
def __setitem__(self, event, value):
226
"""
227
Set the value for a specific event type.
228
229
Args:
230
event (Event): Event type to set
231
value: Value to set (None to delete)
232
"""
233
234
def __contains__(self, event):
235
"""
236
Check if this object has a value for the specified event.
237
238
Args:
239
event (Event): Event type to check
240
241
Returns:
242
bool: True if event is defined
243
"""
244
```
245
246
### Event System
247
248
Event types that define the metrics stored in profile objects.
249
250
```python { .api }
251
class Event:
252
def __init__(self, name, null, aggregator, formatter=str):
253
"""
254
Initialize a new event type.
255
256
Args:
257
name (str): Event name
258
null: Null/default value for this event type
259
aggregator: Function to aggregate multiple values
260
formatter: Function to format values for display
261
"""
262
263
def __repr__(self):
264
"""Return string representation of the event."""
265
266
def null(self):
267
"""
268
Get the null/default value for this event type.
269
270
Returns:
271
The null value
272
"""
273
274
def aggregate(self, values):
275
"""
276
Aggregate multiple values using this event's aggregator.
277
278
Args:
279
values: Iterable of values to aggregate
280
281
Returns:
282
Aggregated result
283
"""
284
285
def format(self, value):
286
"""
287
Format a value for display using this event's formatter.
288
289
Args:
290
value: Value to format
291
292
Returns:
293
str: Formatted value
294
"""
295
296
class UndefinedEvent(Exception):
297
"""Exception raised when accessing undefined event values."""
298
299
def __init__(self, event):
300
"""
301
Initialize with the undefined event.
302
303
Args:
304
event (Event): The event that was undefined
305
"""
306
```
307
308
## Usage Examples
309
310
### Creating and Populating a Profile
311
312
```python
313
import gprof2dot
314
315
# Create a new profile
316
profile = gprof2dot.Profile()
317
318
# Create functions
319
main_func = gprof2dot.Function(1, "main")
320
helper_func = gprof2dot.Function(2, "helper_function")
321
322
# Add functions to profile
323
profile.add_function(main_func)
324
profile.add_function(helper_func)
325
326
# Create call relationship
327
call = gprof2dot.Call(2) # main calls helper_function (id=2)
328
main_func.add_call(call)
329
330
# Set performance metrics
331
main_func[gprof2dot.TIME] = 100.0 # 100ms total time
332
call[gprof2dot.CALLS] = 5 # Called 5 times
333
334
# Validate and process
335
profile.validate()
336
profile.prune(0.01, 0.001, [], False) # Remove nodes <1%, edges <0.1%
337
```
338
339
### Working with Events
340
341
```python
342
# Check if function has timing data
343
if gprof2dot.TIME in main_func:
344
time_value = main_func[gprof2dot.TIME]
345
formatted_time = gprof2dot.TIME.format(time_value)
346
print(f"Function time: {formatted_time}")
347
348
# Aggregate call counts
349
call_counts = [call[gprof2dot.CALLS] for call in main_func.calls.values()]
350
total_calls = gprof2dot.CALLS.aggregate(call_counts)
351
```