std::sort JS profiling data instead of insert-sorting it
authorUlf Hermann <ulf.hermann@theqtcompany.com>
Thu, 13 Aug 2015 16:15:43 +0000 (18:15 +0200)
committerSimon Hausmann <simon.hausmann@theqtcompany.com>
Mon, 24 Aug 2015 19:24:25 +0000 (19:24 +0000)
The original FunctionCall struct is much smaller than the resulting
FunctionCallProperties, and thus not as expensive to copy. Repeatedly
calling upper_bound on a QVector is not such a great idea, either.

Since the usage of QVector instead of QList for the results is new
in Qt 5.6, the insert-sorting got slower, making this change a fix
for a performance regression.

Change-Id: I7154d8cf129b7fbe6e02424fbe16442042a5c3c2
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
src/qml/jsruntime/qv4profiling.cpp
src/qml/jsruntime/qv4profiling_p.h

index 9b77599..b62f367 100644 (file)
@@ -37,8 +37,8 @@
 
 QT_BEGIN_NAMESPACE
 
-using namespace QV4;
-using namespace QV4::Profiling;
+namespace QV4 {
+namespace Profiling {
 
 FunctionCallProperties FunctionCall::resolve() const
 {
@@ -63,26 +63,28 @@ Profiler::Profiler(QV4::ExecutionEngine *engine) : featuresEnabled(0), m_engine(
     m_timer.start();
 }
 
-struct FunctionCallComparator {
-    bool operator()(const FunctionCallProperties &p1, const FunctionCallProperties &p2)
-    { return p1.start < p2.start; }
-};
-
 void Profiler::stopProfiling()
 {
     featuresEnabled = 0;
     reportData();
 }
 
+bool operator<(const FunctionCall &call1, const FunctionCall &call2)
+{
+    return call1.m_start < call2.m_start ||
+            (call1.m_start == call2.m_start && (call1.m_end < call2.m_end ||
+            (call1.m_end == call2.m_end && call1.m_function < call2.m_function)));
+}
+
 void Profiler::reportData()
 {
+    std::sort(m_data.begin(), m_data.end());
     QVector<FunctionCallProperties> resolved;
     resolved.reserve(m_data.size());
-    FunctionCallComparator comp;
-    foreach (const FunctionCall &call, m_data) {
-        FunctionCallProperties props = call.resolve();
-        resolved.insert(std::upper_bound(resolved.begin(), resolved.end(), props, comp), props);
-    }
+
+    foreach (const FunctionCall &call, m_data)
+        resolved.append(call.resolve());
+
     emit dataReady(resolved, m_memory_data);
     m_data.clear();
     m_memory_data.clear();
@@ -111,4 +113,7 @@ void Profiler::startProfiling(quint64 features)
     }
 }
 
+} // namespace Profiling
+} // namespace QV4
+
 QT_END_NAMESPACE
index cc00af0..505d393 100644 (file)
@@ -104,6 +104,7 @@ public:
     FunctionCallProperties resolve() const;
 
 private:
+    friend bool operator<(const FunctionCall &call1, const FunctionCall &call2);
 
     Function *m_function;
     qint64 m_start;