enhance the profile view, close #160

This commit is contained in:
Basile Burg 2017-07-13 12:11:23 +02:00
parent fd3a129e96
commit d104b2651e
No known key found for this signature in database
GPG Key ID: 1868039F415CB8CF
4 changed files with 292 additions and 19 deletions

View File

@ -54,6 +54,7 @@ _Full description of Coedit options. May redirect to a specific widget page._
* [Editor pages](options_editor_pages) * [Editor pages](options_editor_pages)
* [Messages](widgets_messages) * [Messages](widgets_messages)
* [Mini explorer](widgets_mini_explorer) * [Mini explorer](widgets_mini_explorer)
* [Profile viewer](widgets_profile_viewer)
* [Runnable modules](features_runnables) * [Runnable modules](features_runnables)
* [Shortcuts editor](options_shortcuts_editor) * [Shortcuts editor](options_shortcuts_editor)
* [Static macros](widgets_editor) * [Static macros](widgets_editor)

View File

@ -23,8 +23,17 @@ The list displays all the results, which can be inspected more accurately after
#### Toolbar #### Toolbar
- <img src="{%include icurl%}folder/folder.png" class="tlbric"/>: Propose to open the _trace.log_ from a dialog. - <img src="{%include icurl%}other/list.png" class="tlbric"/>: Loads the _trace.log_ file located in the project output path.
- <img src="{%include icurl%}folder/folder.png" class="tlbric"/>: Proposes to open the _trace.log_ from a dialog.
- <img src="{%include icurl%}arrow/arrow_update.png" class="tlbric"/>: Reloads the current _trace.log_ or tries to load it from the current directory. - <img src="{%include icurl%}arrow/arrow_update.png" class="tlbric"/>: Reloads the current _trace.log_ or tries to load it from the current directory.
- <img src="{%include icurl%}cog/wrench.png" class="tlbric"/>: Shows the profile viewer options.
#### Options
- **hideAtributes**: Sets if the functions attributes are displayed.
- **hideRuntimeCalls**: When checked, all the functions starting with `core.` are excluded.
- **hideStandardLibraryCalls**: When checked, all the functions starting with `std.` are excluded.
- **otherExclusion**: Allows to define other sub-strings masks.
{% raw %} {% raw %}
<script> <script>

View File

@ -28,32 +28,32 @@ inherited CEProfileViewerWidget: TCEProfileViewerWidget
AutoSize = True AutoSize = True
MaxWidth = 18 MaxWidth = 18
MinWidth = 18 MinWidth = 18
Width = 0 Width = 18
end end
item item
AutoSize = True AutoSize = True
Caption = 'Num calls' Caption = 'Num calls'
Width = 68 Width = 74
end end
item item
AutoSize = True AutoSize = True
Caption = 'Tree time' Caption = 'Tree time'
Width = 65 Width = 72
end end
item item
AutoSize = True AutoSize = True
Caption = 'Func time' Caption = 'Func time'
Width = 68 Width = 75
end end
item item
AutoSize = True AutoSize = True
Caption = 'Per call' Caption = 'Per call'
Width = 53 Width = 58
end end
item item
AutoSize = True AutoSize = True
Caption = 'function' Caption = 'function'
Width = 60 Width = 244
end> end>
HideSelection = False HideSelection = False
ReadOnly = True ReadOnly = True
@ -129,7 +129,7 @@ inherited CEProfileViewerWidget: TCEProfileViewerWidget
inherited toolbar: TCEToolBar inherited toolbar: TCEToolBar
Width = 543 Width = 543
object btnRefresh: TCEToolButton[0] object btnRefresh: TCEToolButton[0]
Left = 29 Left = 57
Hint = 'reload current trace log file or auto load from the current directory' Hint = 'reload current trace log file or auto load from the current directory'
Top = 0 Top = 0
Caption = 'btnRefresh' Caption = 'btnRefresh'
@ -138,7 +138,7 @@ inherited CEProfileViewerWidget: TCEProfileViewerWidget
scaledSeparator = False scaledSeparator = False
end end
object btnOpen: TCEToolButton[1] object btnOpen: TCEToolButton[1]
Left = 1 Left = 29
Hint = 'open a trace log file' Hint = 'open a trace log file'
Top = 0 Top = 0
Caption = 'btnOpen' Caption = 'btnOpen'
@ -147,7 +147,7 @@ inherited CEProfileViewerWidget: TCEProfileViewerWidget
scaledSeparator = False scaledSeparator = False
end end
object button0: TCEToolButton[2] object button0: TCEToolButton[2]
Left = 57 Left = 113
Height = 28 Height = 28
Top = 0 Top = 0
Width = 13 Width = 13
@ -156,13 +156,13 @@ inherited CEProfileViewerWidget: TCEProfileViewerWidget
scaledSeparator = False scaledSeparator = False
end end
object selPieSource: TComboBox[3] object selPieSource: TComboBox[3]
Left = 70 Left = 126
Height = 23 Height = 36
Hint = 'select the pie representation' Hint = 'select the pie representation'
Top = 0 Top = 0
Width = 154 Width = 154
BorderSpacing.InnerBorder = 3 BorderSpacing.InnerBorder = 3
ItemHeight = 15 ItemHeight = 0
ItemIndex = 0 ItemIndex = 0
Items.Strings = ( Items.Strings = (
'Number of calls' 'Number of calls'
@ -175,6 +175,24 @@ inherited CEProfileViewerWidget: TCEProfileViewerWidget
TabOrder = 0 TabOrder = 0
Text = 'Number of calls' Text = 'Number of calls'
end end
object btnOpts: TCEToolButton[4]
Left = 85
Hint = 'edit profile viewer options'
Top = 0
Caption = 'btnOpts'
OnClick = btnOptsClick
resourceName = 'WRENCH'
scaledSeparator = False
end
object btnProj: TCEToolButton[5]
Left = 1
Hint = 'Try to load using the project output path'
Top = 0
Caption = 'btnProj'
OnClick = btnProjClick
resourceName = 'LIST'
scaledSeparator = False
end
end end
end end
inherited contextMenu: TPopupMenu inherited contextMenu: TPopupMenu

View File

@ -8,12 +8,46 @@ uses
Classes, SysUtils, FileUtil, TASources, TAGraph, TATransformations, TASeries, Classes, SysUtils, FileUtil, TASources, TAGraph, TATransformations, TASeries,
TATools, Forms, Controls, Graphics, Dialogs, ExtCtrls, Menus, ComCtrls, TATools, Forms, Controls, Graphics, Dialogs, ExtCtrls, Menus, ComCtrls,
StdCtrls, TALegend, math, StdCtrls, TALegend, math,
ce_widget, ce_common, ce_stringrange, ce_dsgncontrols, ce_ddemangle; ce_widget, ce_common, ce_stringrange, ce_dsgncontrols, ce_ddemangle,
ce_interfaces, ce_observer, ce_writableComponent;
type type
TCEProfileViewerWidget = class(TCEWidget) TCEProfileViewerOptionsBase = class(TWritableLfmTextComponent)
private
fHideAttributes: boolean;
fHideStandardLibraryCalls: boolean;
fHideRunTimeCalls: boolean;
fOtherExclusions: TStringList;
procedure setOtherExclusions(value: TStringList);
public
constructor create(aOwner: TComponent); override;
destructor destroy; override;
procedure assign(value: TPersistent); override;
published
property hideAttributes: boolean read fHideAttributes write fHideAttributes;
property hideStandardLibraryCalls: boolean read fHideStandardLibraryCalls write fHideStandardLibraryCalls;
property hideRuntimeCalls: boolean read fHideRunTimeCalls write fHideRunTimeCalls;
property otherExclusions: TStringList read fOtherExclusions write setOtherExclusions;
end;
TCEprofileViewerOptions = class(TCEProfileViewerOptionsBase, ICEEditableOptions)
private
fBackup: TCEProfileViewerOptionsBase;
function optionedWantCategory(): string;
function optionedWantEditorKind: TOptionEditorKind;
function optionedWantContainer: TPersistent;
procedure optionedEvent(event: TOptionEditorEvent);
function optionedOptionsModified: boolean;
public
constructor create(aOwner: TComponent); override;
destructor destroy; override;
end;
TCEProfileViewerWidget = class(TCEWidget, ICEProjectObserver)
btnOpen: TCEToolButton; btnOpen: TCEToolButton;
btnOpts: TCEToolButton;
btnProj: TCEToolButton;
btnRefresh: TCEToolButton; btnRefresh: TCEToolButton;
button0: TCEToolButton; button0: TCEToolButton;
ChartToolset1: TChartToolset; ChartToolset1: TChartToolset;
@ -30,36 +64,175 @@ type
pieSeries: TPieSeries; pieSeries: TPieSeries;
Splitter1: TSplitter; Splitter1: TSplitter;
procedure btnOpenClick(Sender: TObject); procedure btnOpenClick(Sender: TObject);
procedure btnProjClick(Sender: TObject);
procedure btnRefreshClick(Sender: TObject); procedure btnRefreshClick(Sender: TObject);
procedure btnOptsClick(Sender: TObject);
procedure selPieSourceSelect(Sender: TObject); procedure selPieSourceSelect(Sender: TObject);
procedure selPieSourceSelectionChange(Sender: TObject; User: boolean); procedure selPieSourceSelectionChange(Sender: TObject; User: boolean);
procedure Splitter1CanResize(Sender: TObject; var NewSize: Integer; procedure Splitter1CanResize(Sender: TObject; var NewSize: Integer; var Accept: Boolean);
var Accept: Boolean);
procedure Splitter1Moved(Sender: TObject); procedure Splitter1Moved(Sender: TObject);
private private
fOptions: TCEprofileViewerOptions;
logFname: string; logFname: string;
fProj: ICECommonProject;
procedure updateIcons; procedure updateIcons;
procedure clearViewer; procedure clearViewer;
procedure updateFromFile(const fname: string); procedure updateFromFile(const fname: string);
procedure updatePie; procedure updatePie;
procedure listCompare(Sender: TObject; item1, item2: TListItem; Data: Integer; var Compare: Integer); procedure listCompare(Sender: TObject; item1, item2: TListItem; Data: Integer; var Compare: Integer);
procedure projNew(project: ICECommonProject);
procedure projChanged(project: ICECommonProject);
procedure projClosing(project: ICECommonProject);
procedure projFocused(project: ICECommonProject);
procedure projCompiling(project: ICECommonProject);
procedure projCompiled(project: ICECommonProject; success: boolean);
public public
constructor create(aOwner: TComponent); override; constructor create(aOwner: TComponent); override;
destructor destroy; override;
procedure reloadCurrent;
end; end;
const optFname = 'profileviewer.txt';
implementation implementation
{$R *.lfm} {$R *.lfm}
constructor TCEProfileViewerOptionsBase.create(aOwner: TComponent);
begin
inherited create(aOwner);
fOtherExclusions := TStringList.Create;
end;
destructor TCEProfileViewerOptionsBase.destroy;
begin
fOtherExclusions.free;
inherited;
end;
procedure TCEProfileViewerOptionsBase.assign(value: TPersistent);
var
s: TCEProfileViewerOptionsBase;
begin
if value is TCEProfileViewerOptionsBase then
begin
s := TCEProfileViewerOptionsBase(value);
fOtherExclusions.Assign(s.fOtherExclusions);
fHideRunTimeCalls:=s.fHideRunTimeCalls;
fHideStandardLibraryCalls:=fHideStandardLibraryCalls;
end
else inherited;
end;
procedure TCEProfileViewerOptionsBase.setOtherExclusions(value: TStringList);
begin
fOtherExclusions.assign(value);
end;
constructor TCEprofileViewerOptions.create(aOwner: TComponent);
var
s: string;
begin
inherited create(aOwner);
fBackup := TCEProfileViewerOptionsBase.create(nil);
EntitiesConnector.addObserver(self);
s := getCoeditDocPath + optFname;
if s.fileExists then
loadFromFile(s);
end;
destructor TCEprofileViewerOptions.destroy;
begin
saveTofile(getCoeditDocPath + optFname);
EntitiesConnector.removeObserver(self);
fBackup.free;
inherited;
end;
function TCEprofileViewerOptions.optionedWantCategory(): string;
begin
result := 'Profile viewer';
end;
function TCEprofileViewerOptions.optionedWantEditorKind: TOptionEditorKind;
begin
result := oekGeneric;
end;
function TCEprofileViewerOptions.optionedWantContainer: TPersistent;
begin
result := self;
end;
procedure TCEprofileViewerOptions.optionedEvent(event: TOptionEditorEvent);
begin
case event of
oeeAccept:
begin
fBackup.assign(self);
TCEProfileViewerWidget(owner).reloadCurrent;
end;
oeeCancel:
begin
self.assign(fBackup);
TCEProfileViewerWidget(owner).reloadCurrent;
end;
oeeSelectCat:
fBackup.assign(self);
oeeChange:
TCEProfileViewerWidget(owner).reloadCurrent;
end;
end;
function TCEprofileViewerOptions.optionedOptionsModified: boolean;
begin
result := false;
end;
constructor TCEProfileViewerWidget.create(aOwner: TComponent); constructor TCEProfileViewerWidget.create(aOwner: TComponent);
begin begin
inherited; inherited;
EntitiesConnector.addObserver(self);
fOptions:= TCEprofileViewerOptions.create(self);
clearViewer; clearViewer;
updatePie; updatePie;
list.OnCompare:=@listCompare; list.OnCompare:=@listCompare;
selPieSourceSelect(nil); selPieSourceSelect(nil);
end; end;
procedure TCEProfileViewerWidget.btnRefreshClick(Sender: TObject); destructor TCEProfileViewerWidget.destroy;
begin
EntitiesConnector.removeObserver(self);
inherited;
end;
procedure TCEProfileViewerWidget.projNew(project: ICECommonProject);
begin
end;
procedure TCEProfileViewerWidget.projChanged(project: ICECommonProject);
begin
end;
procedure TCEProfileViewerWidget.projClosing(project: ICECommonProject);
begin
if project = fProj then
fProj := nil;
end;
procedure TCEProfileViewerWidget.projFocused(project: ICECommonProject);
begin
fProj := project;
end;
procedure TCEProfileViewerWidget.projCompiling(project: ICECommonProject);
begin
end;
procedure TCEProfileViewerWidget.projCompiled(project: ICECommonProject; success: boolean);
begin
end;
procedure TCEProfileViewerWidget.reloadCurrent;
var var
fname: string; fname: string;
begin begin
@ -76,6 +249,16 @@ begin
end; end;
end; end;
procedure TCEProfileViewerWidget.btnRefreshClick(Sender: TObject);
begin
reloadCurrent;
end;
procedure TCEProfileViewerWidget.btnOptsClick(Sender: TObject);
begin
getOptionsEditor.showOptionEditor(fOptions as ICEEditableOptions);
end;
procedure TCEProfileViewerWidget.selPieSourceSelect(Sender: TObject); procedure TCEProfileViewerWidget.selPieSourceSelect(Sender: TObject);
begin begin
case selPieSource.ItemIndex of case selPieSource.ItemIndex of
@ -103,6 +286,21 @@ begin
end; end;
end; end;
procedure TCEProfileViewerWidget.btnProjClick(Sender: TObject);
var
fname: string;
begin
if assigned(fProj) then
begin
fname := fProj.outputFilename.extractFileDir + DirectorySeparator + 'trace.log';
if fileExists(fname) then
begin
updateFromFile(fname);
logFname:=fname;
end;
end;
end;
procedure TCEProfileViewerWidget.updatePie; procedure TCEProfileViewerWidget.updatePie;
begin begin
pieSeries.FixedRadius:= max(1, pie.Height div 2 - 10); pieSeries.FixedRadius:= max(1, pie.Height div 2 - 10);
@ -176,6 +374,7 @@ var
fft: qword; fft: qword;
ftt: qword; ftt: qword;
fpc: qword; fpc: qword;
exc: string;
procedure fillRow(); procedure fillRow();
var var
@ -196,6 +395,47 @@ var
datPerCall.Add(0, fpc, idt, c); datPerCall.Add(0, fpc, idt, c);
end; end;
function canShow: boolean;
begin
result := true;
if fOptions.hideRuntimeCalls and (Pos(' core.', idt) > 0) then
exit(false);
if fOptions.hideStandardLibraryCalls and (Pos(' std.', idt) > 0) then
exit(false);
if fOptions.otherExclusions.Count > 0 then
for exc in fOptions.otherExclusions do
if Pos(exc, idt) > 0 then
exit(false);
end;
procedure filterAttributes;
const
a: array[0..12] of string = ('const','pure','nothrow','@safe','@nogc',
'@trusted', '@system', 'immutable', 'inout', 'return', '@property',
'shared', 'scope');
var
i: integer = 0;
j: integer;
p: integer;
s: string;
begin
if not fOptions.hideAttributes then
exit;
p := pos('(', idt);
if p = 0 then
p := integer.MaxValue;
for s in a do
begin
j := pos(s, idt);
if (j > 0) then
j += s.length + 1;
if (j < p) and (j >= i) then
i := j;
end;
if i > 0 then
idt := idt[i..idt.length];
end;
begin begin
clearViewer; clearViewer;
@ -272,7 +512,12 @@ begin
rng.popWhile(' ')^.empty; rng.popWhile(' ')^.empty;
idt := demangle(rng.takeUntil(#10).yield); idt := demangle(rng.takeUntil(#10).yield);
// apply options and add item
if canShow then
begin
filterAttributes;
fillRow; fillRow;
end;
if not rng.empty then if not rng.empty then
rng.popFront rng.popFront