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
43 changes: 34 additions & 9 deletions src/AnalysisExporter/FileCompilations/FileCompilationsExporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <fstream>
#include <algorithm>
#include <chrono>

FileCompilationsExporter::FileCompilationsExporter(const TFileCompilationDataPerFile& data)
: m_data(data)
Expand All @@ -12,6 +13,7 @@ FileCompilationsExporter::~FileCompilationsExporter()
{
}

template<typename T>
bool FileCompilationsExporter::ExportTo(const std::string& path) const
{
std::ofstream out(path);
Expand All @@ -37,23 +39,46 @@ bool FileCompilationsExporter::ExportTo(const std::string& path) const
return lhsTotalDuration > rhsTotalDuration;
});

std::string timeType = "nanoseconds";

if (std::is_same<T, std::chrono::seconds>::value)
{
timeType = "seconds";
}
else if (std::is_same<T, std::chrono::milliseconds>::value)
{
timeType = "miliseconds";
}

// write data header to stream
out << "File path" << ";"
<< "Compilation time (nanoseconds)" << ";"
<< "Front-end time (nanoseconds)" << ";"
<< "Back-end time (nanoseconds)" << std::endl;
<< "Compilation time (" << timeType << ")" << ";"
<< "Front-end time (" << timeType << ")" << ";"
<< "Back-end time (" << timeType << ")" << std::endl;

// write data to stream
for (auto&& data : dataPerFile)
{
std::chrono::nanoseconds totalDuration = data->second.BackEnd.Stop - data->second.FrontEnd.Start;

const FileCompilationData& perFile = data->second;
T compileTime = std::chrono::duration_cast<T>(perFile.BackEnd.Stop - perFile.FrontEnd.Start);
T frontEndTime = std::chrono::duration_cast<T>(perFile.FrontEnd.Stop - perFile.FrontEnd.Start);
T backEndTime = std::chrono::duration_cast<T>(perFile.BackEnd.Stop - perFile.BackEnd.Start);

out << data->first << ";"
<< (data->second.BackEnd.Stop - data->second.FrontEnd.Start).count() << ";"
<< (data->second.FrontEnd.Stop - data->second.FrontEnd.Start).count() << ";"
<< (data->second.BackEnd.Stop - data->second.BackEnd.Start).count() << std::endl;
<< compileTime.count() << ";"
<< frontEndTime.count() << ";"
<< backEndTime.count() << std::endl;
}

out.close();
return true;
}
}

template
bool FileCompilationsExporter::ExportTo<std::chrono::seconds>(const std::string& path) const;

template
bool FileCompilationsExporter::ExportTo<std::chrono::milliseconds>(const std::string& path) const;

template
bool FileCompilationsExporter::ExportTo<std::chrono::nanoseconds>(const std::string& path) const;
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class FileCompilationsExporter
~FileCompilationsExporter();

// exports to CSV
template<typename T>
bool ExportTo(const std::string& path) const;

private:
Expand Down
39 changes: 31 additions & 8 deletions src/AnalysisExporter/FileInclusions/FileInclusionTimesExporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ FileInclusionTimesExporter::~FileInclusionTimesExporter()
{
}

template<typename T>
bool FileInclusionTimesExporter::ExportTo(const std::string& path) const
{
std::ofstream out(path);
Expand Down Expand Up @@ -80,25 +81,47 @@ bool FileInclusionTimesExporter::ExportTo(const std::string& path) const
return lhs.AverageInclusionTime > rhs.AverageInclusionTime;
});


std::string timeType = "nanoseconds";

if (std::is_same<T, std::chrono::seconds>::value)
{
timeType = "seconds";
}
else if (std::is_same<T, std::chrono::milliseconds>::value)
{
timeType = "miliseconds";
}

// write data header to stream
out << "File path" << ";"
<< "Average elapsed time (nanoseconds)" << ";"
<< "Minimum elapsed time (nanoseconds)" << ";"
<< "Maximum elapsed time (nanoseconds)" << ";"
<< "Standard deviation (nanoseconds)" << ";"
<< "Average elapsed time (" << timeType << ")" << ";"
<< "Minimum elapsed time (" << timeType << ")" << ";"
<< "Maximum elapsed time (" << timeType << ")" << ";"
<< "Standard deviation (" << timeType << ")" << ";"
<< "Occurrences" << std::endl;

// write data to stream
for (auto&& data : dataPerFile)
{
out << (*data.FilePath) << ";"
<< data.AverageInclusionTime.count() << ";"
<< data.MinimumInclusionTime.count() << ";"
<< data.MaximumInclusionTime.count() << ";"
<< data.StandardDeviation.count() << ";"
<< std::chrono::duration_cast<T>(data.AverageInclusionTime).count() << ";"
<< std::chrono::duration_cast<T>(data.MinimumInclusionTime).count() << ";"
<< std::chrono::duration_cast<T>(data.MaximumInclusionTime).count() << ";"
<< std::chrono::duration_cast<T>(data.StandardDeviation).count() << ";"
<< data.Occurrences << std::endl;
}

out.close();
return true;
}

template
bool FileInclusionTimesExporter::ExportTo<std::chrono::seconds>(const std::string& path) const;

template
bool FileInclusionTimesExporter::ExportTo<std::chrono::milliseconds>(const std::string& path) const;

template
bool FileInclusionTimesExporter::ExportTo<std::chrono::nanoseconds>(const std::string& path) const;

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class FileInclusionTimesExporter
~FileInclusionTimesExporter();

// exports to CSV format
template<typename T>
bool ExportTo(const std::string& path) const;

private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ FunctionCompilationsExporter::~FunctionCompilationsExporter()
{
}

template<typename T>
bool FunctionCompilationsExporter::ExportTo(const std::string& path) const
{
std::ofstream out = std::ofstream(path);
Expand Down Expand Up @@ -83,26 +84,48 @@ bool FunctionCompilationsExporter::ExportTo(const std::string& path) const
return lhs.AverageCompilationTime > rhs.AverageCompilationTime;
});


std::string timeType = "nanoseconds";

if (std::is_same<T, std::chrono::seconds>::value)
{
timeType = "seconds";
}
else if (std::is_same<T, std::chrono::milliseconds>::value)
{
timeType = "miliseconds";
}

// write data header to stream
out << "Undecorated function name" << ";"
<< "Average elapsed time (nanoseconds)" << ";"
<< "Minimum elapsed time (nanoseconds)" << ";"
<< "Maximum elapsed time (nanoseconds)" << ";"
<< "Standard deviation (nanoseconds)" << ";"
<< "Average elapsed time (" << timeType << ")" << ";"
<< "Minimum elapsed time (" << timeType << ")" << ";"
<< "Maximum elapsed time (" << timeType << ")" << ";"
<< "Standard deviation (" << timeType << ")" << ";"
<< "Occurrences" << std::endl;

// write data to file
for (auto&& data : dataPerFunction)
{
// dump to stream
out << Utilities::CppBuildInsightsDataConversion::UndecorateFunction(*data.FunctionName) << ";"
<< data.AverageCompilationTime.count() << ";"
<< data.MinimumCompilationTime.count() << ";"
<< data.MaximumCompilationTime.count() << ";"
<< std::chrono::duration_cast<T>(data.AverageCompilationTime).count() << ";"
<< std::chrono::duration_cast<T>(data.MinimumCompilationTime).count() << ";"
<< std::chrono::duration_cast<T>(data.MaximumCompilationTime).count() << ";"
<< data.StandardDeviation.count() << ";"
<< data.Occurrences << std::endl;
}

out.close();
return true;
}

template
bool FunctionCompilationsExporter::ExportTo<std::chrono::seconds>(const std::string& path) const;

template
bool FunctionCompilationsExporter::ExportTo<std::chrono::milliseconds>(const std::string& path) const;

template
bool FunctionCompilationsExporter::ExportTo<std::chrono::nanoseconds>(const std::string& path) const;

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class FunctionCompilationsExporter
~FunctionCompilationsExporter();

// exports to CSV format
template<typename T>
bool ExportTo(const std::string& path) const;

private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,16 @@ bool TemplateInstantiationsExporter::ExportTo(const std::string& path) const
// aggregate data
typedef std::unordered_map<std::string, DataPerTemplate> TAggregatedData;
TAggregatedData aggregatedData;

std::string symbolName = "Unknown";

for (auto&& pair : m_templateInstantiations)
{
const std::chrono::nanoseconds& timeElapsed = pair.second.Duration;

auto itSpecializationTemplateName = m_symbolNames.find(pair.second.Specialization);
assert(itSpecializationTemplateName != m_symbolNames.end());

// from the docs: "Comparing types between different compiler front-end passes requires using symbol names"
auto result = aggregatedData.try_emplace(itSpecializationTemplateName->second, DataPerTemplate());
auto& data = result.first->second;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,5 @@ const wchar_t* FileCompilationsAnalyzer::GetFilePath(const CppBI::Activities::Co

assert(compilerPass.OutputObjectPath() != nullptr);
return compilerPass.OutputObjectPath();

}
41 changes: 35 additions & 6 deletions src/BuildAnalyzer/BuildAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,40 @@ std::vector<CppBI::IAnalyzer*> BuildAnalyzer::BuildAnalyzerList(const AnalysisOp
return analyzers;
}

bool BuildAnalyzer::ExportFunctionCompilationsData(const std::string& path) const
bool BuildAnalyzer::ExportFunctionCompilationsData(const std::string& path, TimeDisplayEnum timeDisplay) const
{
assert(m_analysisPerformed);

FunctionCompilationsExporter exporter(m_functionCompilations.GetData());
return exporter.ExportTo(path);

if (timeDisplay == TimeDisplayEnum::Seconds)
{
return exporter.ExportTo<std::chrono::seconds>(path);
}
else if (timeDisplay == TimeDisplayEnum::Milliseconds)
{
return exporter.ExportTo<std::chrono::milliseconds>(path);
}

return exporter.ExportTo<std::chrono::nanoseconds>(path);
}

bool BuildAnalyzer::ExportFileInclusionTimesData(const std::string& path) const
bool BuildAnalyzer::ExportFileInclusionTimesData(const std::string& path, TimeDisplayEnum timeDisplay) const
{
assert(m_analysisPerformed);

FileInclusionTimesExporter exporter(m_fileInclusions.GetTimeData());
return exporter.ExportTo(path);

if (timeDisplay == TimeDisplayEnum::Seconds)
{
return exporter.ExportTo<std::chrono::seconds>(path);
}
else if (timeDisplay == TimeDisplayEnum::Milliseconds)
{
return exporter.ExportTo<std::chrono::milliseconds>(path);
}

return exporter.ExportTo<std::chrono::nanoseconds>(path);
}

bool BuildAnalyzer::ExportFileInclusionGraph(const std::string& path) const
Expand All @@ -107,12 +127,21 @@ bool BuildAnalyzer::ExportFileInclusionGraph(const std::string& path) const
return exporter.ExportTo(path);
}

bool BuildAnalyzer::ExportFileCompilationsData(const std::string& path) const
bool BuildAnalyzer::ExportFileCompilationsData(const std::string& path, TimeDisplayEnum timeDisplay) const
{
assert(m_analysisPerformed);

FileCompilationsExporter exporter(m_fileCompilations.GetData());
return exporter.ExportTo(path);
if (timeDisplay == TimeDisplayEnum::Seconds)
{
return exporter.ExportTo<std::chrono::seconds>(path);
}
else if (timeDisplay == TimeDisplayEnum::Milliseconds)
{
return exporter.ExportTo<std::chrono::milliseconds>(path);
}

return exporter.ExportTo<std::chrono::nanoseconds>(path);
}

bool BuildAnalyzer::ExportBuildTimeline(const std::string& path) const
Expand Down
14 changes: 11 additions & 3 deletions src/BuildAnalyzer/BuildAnalyzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ namespace Microsoft { namespace Cpp { namespace BuildInsights {
class BuildAnalyzer
{
public:
enum class TimeDisplayEnum
{
Nanoseconds,
Milliseconds,
Seconds,
};

struct AnalysisOptions
{
std::chrono::milliseconds TimelineIgnoreFunctionsUnder = std::chrono::milliseconds(0);
Expand All @@ -27,6 +34,7 @@ class BuildAnalyzer
bool FileCompilations = true;
bool BuildTimeline = true;
bool TemplateInstantiations = true;
TimeDisplayEnum TimeDisplay = TimeDisplayEnum::Nanoseconds;
};

public:
Expand All @@ -36,10 +44,10 @@ class BuildAnalyzer
inline bool IsAnalysisPerformed() const { return m_analysisPerformed; }

bool Analyze();
bool ExportFunctionCompilationsData(const std::string& path) const;
bool ExportFileInclusionTimesData(const std::string& path) const;
bool ExportFunctionCompilationsData(const std::string& path, TimeDisplayEnum timeDisplay) const;
bool ExportFileInclusionTimesData(const std::string& path, TimeDisplayEnum timeDisplay) const;
bool ExportFileInclusionGraph(const std::string& path) const;
bool ExportFileCompilationsData(const std::string& path) const;
bool ExportFileCompilationsData(const std::string& path, TimeDisplayEnum timeDisplay) const;
bool ExportBuildTimeline(const std::string& path) const;
bool ExportTemplateInstantiationsData(const std::string& path) const;

Expand Down
Loading