Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,6 @@ class JsonSettings(
override fun filesDir() = filesDirName

override var shouldShowToolbar: Boolean = false
override var lastVersion: String = ""

private fun initWithDefaults() {
initWithDefaultStringValue(SETTINGS_FONT_NAME, "Arial")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.github.grishberg.profiler.analyzer

import com.github.grishberg.profiler.core.AnalyzerResult
import java.io.File

class AllThreadsMethodsReportGenerator(
private val data: AnalyzerResult,
) : ReportGenerator {

override fun generate(
file: File, onlyConstructor: Boolean, minimumDurationInMs: Int, packageFilter: String
) {
val baseDir = file.path

data.threads.forEach { threadItem ->
val profileData = data.data[threadItem.threadId] ?: return
val reportFile = File(baseDir, normalizeFileName(threadItem.name))
val singleThreadReportGenerator = FlatMethodsReportGenerator(profileData)
singleThreadReportGenerator.generate(
reportFile, onlyConstructor, minimumDurationInMs, packageFilter
)
}
}

private fun normalizeFileName(threadName: String): String {
return threadName.replace("/", "_").replace("\\", "_").replace(":", "_")
}
}
Original file line number Diff line number Diff line change
@@ -1,41 +1,51 @@
package com.github.grishberg.profiler.analyzer

import com.github.grishberg.profiler.core.ProfileData
import com.github.grishberg.profiler.chart.BookmarksRectangle
import com.github.grishberg.profiler.chart.CallTracePanel
import com.github.grishberg.profiler.core.ProfileData
import java.io.BufferedWriter
import java.io.File
import java.io.FileOutputStream
import java.io.OutputStreamWriter

class FlatMethodsReportGenerator(
private val data: CallTracePanel.ProfilerPanelData
private val profileData: List<ProfileData>,
private val markers: List<BookmarksRectangle> = emptyList(),
) : ReportGenerator {

override fun generate(file: File, onlyConstructor: Boolean, minimumDurationInMs: Int) {
override fun generate(
file: File,
onlyConstructor: Boolean,
minimumDurationInMs: Int,
packageFilter: String
) {
val fos = FileOutputStream(file)

BufferedWriter(OutputStreamWriter(fos)).use { bw ->
bw.write("name\tglobal time\tthread time\tglobal self time\tthread self time")
bw.newLine()

data.profileData.forEach {
val threadDuration =
it.profileData.threadEndTimeInMillisecond - it.profileData.threadStartTimeInMillisecond
val globalDuration =
it.profileData.globalEndTimeInMillisecond - it.profileData.globalStartTimeInMillisecond
if (threadDuration > minimumDurationInMs && (!onlyConstructor || isConstructor(it.profileData.name))) {
profileData.forEach {
val threadDuration = it.threadEndTimeInMillisecond - it.threadStartTimeInMillisecond
val globalDuration = it.globalEndTimeInMillisecond - it.globalStartTimeInMillisecond
if (threadDuration > minimumDurationInMs && (!onlyConstructor || isConstructor(it.name)) && (packageFilter.isEmpty() || it.name.startsWith(
packageFilter
))
) {
bw.write(
String.format(
"%s\t%.3f\t%.3f\t%.3f\t%.3f",
it.profileData.name, globalDuration, threadDuration,
it.profileData.globalSelfTime, it.profileData.threadSelfTime
it.name,
globalDuration,
threadDuration,
it.globalSelfTime,
it.threadSelfTime
)
)
bw.newLine()
}

val markerRectangle = findMarkerForElement(it.profileData)
val markerRectangle = findMarkerForElement(it)
if (markerRectangle != null) {
bw.write("<marker>: ${markerRectangle.name}")
bw.newLine()
Expand All @@ -45,7 +55,7 @@ class FlatMethodsReportGenerator(
}

private fun findMarkerForElement(profileData: ProfileData): BookmarksRectangle? {
for (marker in data.markersData) {
for (marker in markers) {
if (marker.isForElement(profileData)) {
return marker
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package com.github.grishberg.profiler.analyzer

import com.github.grishberg.profiler.core.ProfileData
import java.io.File

interface ReportGenerator {
fun generate(file: File, onlyConstructor: Boolean, minimumDurationInMs: Int)
fun generate(
file: File,
onlyConstructor: Boolean,
minimumDurationInMs: Int,
packageFilter: String
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ class KeyBinder(

private inner class GenerateReportsAction : AbstractAction() {
override fun actionPerformed(e: ActionEvent) {
dialogDelegate.showReportsDialog()
dialogDelegate.showCurrentThreadMethodsReportsDialog()
}
}

Expand Down
41 changes: 39 additions & 2 deletions core/src/main/java/com/github/grishberg/profiler/ui/Main.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.github.grishberg.profiler.ui;

import com.github.grishberg.profiler.analyzer.AllThreadsMethodsReportGenerator;
import com.github.grishberg.profiler.analyzer.FlatMethodsReportGenerator;
import com.github.grishberg.profiler.analyzer.ReportGenerator;
import com.github.grishberg.profiler.chart.*;
import com.github.grishberg.profiler.chart.flame.FlameChartController;
import com.github.grishberg.profiler.chart.flame.FlameChartDialog;
Expand Down Expand Up @@ -492,6 +494,12 @@ private JMenu createFileMenu() {

JMenuItem deleteCurrentFile = new JMenuItem("Delete current file");

JMenuItem generateCurrentThreadMethodsReportFor = new JMenuItem("Current thread methods duration report");
generateCurrentThreadMethodsReportFor.setAccelerator(MenuAcceleratorHelperKt.createControlAccelerator('P'));

JMenuItem generateAllThreadMethodsReportFor = new JMenuItem("All threads methods duration report");


file.add(openFile);
file.add(openFileInNewWindow);
file.add(openMappingFile);
Expand All @@ -502,6 +510,10 @@ private JMenu createFileMenu() {
file.addSeparator();
file.add(openTracesDirInExternalFileManager);
file.add(deleteCurrentFile);
file.addSeparator();
file.add(generateCurrentThreadMethodsReportFor);
file.add(generateAllThreadMethodsReportFor);


openFile.addActionListener(arg0 -> showOpenFileChooser(false));
openFileInNewWindow.addActionListener(arg0 -> showOpenFileChooser(true));
Expand All @@ -511,6 +523,9 @@ private JMenu createFileMenu() {
exportTraceWithBookmarks.addActionListener(arg0 -> exportTraceWithBookmarks());
openTracesDirInExternalFileManager.addActionListener(arg -> openTracesDirInExternalFileManager());
deleteCurrentFile.addActionListener(arg -> deleteCurrentFile());
generateCurrentThreadMethodsReportFor.addActionListener(arg -> showCurrentThreadMethodsReportsDialog());
generateAllThreadMethodsReportFor.addActionListener(arg -> showAllThreadReportsDialog());

file.addSeparator();
return file;
}
Expand Down Expand Up @@ -1142,10 +1157,32 @@ public void showErrorDialog(String title, String errorMessage) {
}

@Override
public void showReportsDialog() {
public void showCurrentThreadMethodsReportsDialog() {
final TraceContainer currentResultContainer = resultContainer;
if (currentResultContainer == null) {
log.d("There is no any opened trace file");
return;
}
hoverInfoPanel.hidePanel();

FlatMethodsReportGenerator generator = new FlatMethodsReportGenerator(chart.getCurrentThreadMethods(), chart.getData().markersData);
ReportsGeneratorDialog reportsGeneratorDialog = new ReportsGeneratorDialog(frame, settings, generator);
reportsGeneratorDialog.pack();

reportsGeneratorDialog.setLocationRelativeTo(frame);
reportsGeneratorDialog.setVisible(true);
}

@Override
public void showAllThreadReportsDialog() {
final TraceContainer currentResultContainer = resultContainer;
if (currentResultContainer == null) {
log.d("There is no any opened trace file");
return;
}
hoverInfoPanel.hidePanel();

FlatMethodsReportGenerator generator = new FlatMethodsReportGenerator(chart.getData());
final ReportGenerator generator = new AllThreadsMethodsReportGenerator(currentResultContainer.getResult());
ReportsGeneratorDialog reportsGeneratorDialog = new ReportsGeneratorDialog(frame, settings, generator);
reportsGeneratorDialog.pack();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import javax.swing.JMenu
import javax.swing.JMenuItem

private const val MAX_HISTORY_SIZE = 10
private const val FILE_MENU_ITEMS_COUNT_BEFORE_HISTORY = 11
private const val FILE_MENU_ITEMS_COUNT_BEFORE_HISTORY = 14


class MenuHistoryItems(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.github.grishberg.profiler.ui
interface ShowDialogDelegate {
fun showOpenFileChooser(inNewWindow: Boolean = false)
fun showNewTraceDialog(inNewWindow: Boolean = false)
fun showReportsDialog()
fun showCurrentThreadMethodsReportsDialog()
fun showAllThreadReportsDialog()
fun showScaleRangeDialog()
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.github.grishberg.profiler.ui.dialogs
import com.github.grishberg.profiler.analyzer.ReportGenerator
import com.github.grishberg.profiler.common.JNumberField
import com.github.grishberg.profiler.common.settings.SettingsFacade
import com.github.grishberg.profiler.ui.Main
import java.awt.Frame
import java.awt.GridBagConstraints
import java.awt.GridBagLayout
Expand All @@ -16,6 +15,7 @@ import javax.swing.JComponent
import javax.swing.JFileChooser
import javax.swing.JLabel
import javax.swing.JPanel
import javax.swing.JTextField
import javax.swing.border.EmptyBorder
import javax.swing.filechooser.FileNameExtensionFilter

Expand All @@ -28,6 +28,7 @@ class ReportsGeneratorDialog(

private val constructorsCheckbox: JCheckBox
private val durationLimit: JNumberField
private val packageFilter: JTextField

init {
val content = JPanel()
Expand Down Expand Up @@ -56,9 +57,14 @@ class ReportsGeneratorDialog(
durationLimit.value = 0
addLabelAndField(
content, labelConstraints, fieldConstraints,
"minimum duration", durationLimit, "If checked - will be exported only constructors"
"minimum duration", durationLimit, "Minimum global time duration in ms"
)

packageFilter = JTextField(20)
addLabelAndField(
content, labelConstraints, fieldConstraints,
"package filter", packageFilter, "If not empty - show methods with given package prefix"
)
fieldConstraints.gridy++
fieldConstraints.gridwidth = 2

Expand Down Expand Up @@ -102,11 +108,16 @@ class ReportsGeneratorDialog(

if (userSelection == JFileChooser.APPROVE_OPTION) {
var fileToSave = fileChooser.selectedFile
if (fileToSave.extension.toLowerCase() != "txt") {
if (fileToSave.extension.lowercase() != "txt") {
fileToSave = File(fileToSave.absolutePath + ".txt")
}
settings.reportsFileDialogDir = fileToSave.parent
reportsGeneratorDelegate.generate(fileToSave, constructorsCheckbox.isSelected, durationLimit.value as Int)
reportsGeneratorDelegate.generate(
fileToSave,
constructorsCheckbox.isSelected,
durationLimit.value as Int,
packageFilter.text.trim()
)
isVisible = false
}
}
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ studioCompilePath=/Applications/Android Studio.app/Contents

pluginGroup = com.github.grishberg
pluginName = android-methods-profiler
yampVersion = 23.08.25
yampVersion = 24.02.06

# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
# for insight into build numbers and IntelliJ Platform versions.
Expand Down