From 297f37a63a53635b29e8369622764d84c176c8c4 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 18 Dec 2019 01:10:16 +0100 Subject: [PATCH] Huge performance improvement for a specific array element interaction. Reason: duplicate cluster interactions spoiled performance. --- src/db/db/dbHierNetworkProcessor.cc | 29 ++++++++++++++-- src/lay/lay/layMainWindow.cc | 27 +++------------ src/lay/lay/layProgressWidget.cc | 51 ++++++++++++++++++++--------- src/lay/lay/layProgressWidget.h | 11 ++++--- src/tl/tl/tlProgress.cc | 12 ++++--- src/tl/tl/tlProgress.h | 2 +- 6 files changed, 82 insertions(+), 50 deletions(-) diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index 8f5f74fda..1bb053cbc 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -1167,6 +1167,11 @@ public: : cluster_id (_cluster_id), other_ci (_other_ci) { } + bool operator== (const ClusterInstanceInteraction &other) const + { + return cluster_id == other.cluster_id && other_ci == other.other_ci; + } + size_t cluster_id; ClusterInstance other_ci; }; @@ -1211,6 +1216,7 @@ public: db::ICplxTrans t; consider_cluster_instance_pair (*c1, *i2, t, ic); + ic.unique (); m_ci_interactions.splice (m_ci_interactions.end (), ic, ic.begin (), ic.end ()); } @@ -1411,6 +1417,8 @@ private: for (std::list >::iterator i = ii_interactions.begin (); i != ii_interactions.end (); ++i) { propagate_cluster_inst (i->second, i2.cell_index (), i2t, i2.prop_id ()); } + + ii_interactions.unique (); interacting_clusters.splice (interacting_clusters.end (), ii_interactions, ii_interactions.begin (), ii_interactions.end ()); } @@ -1436,6 +1444,8 @@ private: for (std::list >::iterator i = ii_interactions.begin (); i != ii_interactions.end (); ++i) { propagate_cluster_inst (i->first, i1.cell_index (), i1t, i1.prop_id ()); } + + ii_interactions.unique (); interacting_clusters.splice (interacting_clusters.end (), ii_interactions, ii_interactions.begin (), ii_interactions.end ()); } @@ -1448,15 +1458,28 @@ private: } - cluster_instance_pair_list_type &cached = (*mp_instance_interaction_cache) [ii_key]; - cached = interacting_clusters; + // remove duplicates (after doing a quick unique before) + // NOTE: duplicates may happen due to manifold child/child interactions which boil down to + // identical parent cluster interactions. + std::vector > sorted_interactions; + sorted_interactions.reserve (interacting_clusters.size ()); + sorted_interactions.insert (sorted_interactions.end (), interacting_clusters.begin (), interacting_clusters.end ()); + interacting_clusters.clear (); + std::sort (sorted_interactions.begin (), sorted_interactions.end ()); + sorted_interactions.erase (std::unique (sorted_interactions.begin (), sorted_interactions.end ()), sorted_interactions.end ()); + + // return the list of unique interactions + interacting_clusters.insert (interacting_clusters.end (), sorted_interactions.begin (), sorted_interactions.end ()); // normalize transformations in cache db::ICplxTrans i1ti = i1t.inverted (), i2ti = i2t.inverted (); - for (std::list >::iterator i = cached.begin (); i != cached.end (); ++i) { + for (std::vector >::iterator i = sorted_interactions.begin (); i != sorted_interactions.end (); ++i) { i->first.transform (i1ti); i->second.transform (i2ti); } + + cluster_instance_pair_list_type &cached = (*mp_instance_interaction_cache) [ii_key]; + cached.insert (cached.end (), sorted_interactions.begin (), sorted_interactions.end ()); } /** diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index 0a3924964..682f20c84 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -136,19 +136,9 @@ public: } } - void set_can_cancel (bool f) + void set_progress (tl::Progress *progress) { - mp_progress_widget->set_can_cancel (f); - } - - void set_text (const std::string &text) - { - mp_progress_widget->set_text (text); - } - - void set_value (double v, const std::string &value) - { - mp_progress_widget->set_value (v, value); + mp_progress_widget->set_progress (progress); } void add_widget (QWidget *widget) @@ -4732,23 +4722,14 @@ MainWindow::progress_get_widget () const bool MainWindow::update_progress (tl::Progress *progress) { - bool can_cancel = progress->can_cancel (); - std::string text = progress->desc (); - std::string value = progress->formatted_value (); - double v = progress->value (); - if (mp_progress_dialog) { - mp_progress_dialog->set_can_cancel (can_cancel); - mp_progress_dialog->set_text (text); - mp_progress_dialog->set_value (v, value); + mp_progress_dialog->set_progress (progress); return true; } else if (isVisible () && mp_progress_widget) { - mp_progress_widget->set_can_cancel (can_cancel); - mp_progress_widget->set_text (text); - mp_progress_widget->set_value (v, value); + mp_progress_widget->set_progress (progress); return true; } else { diff --git a/src/lay/lay/layProgressWidget.cc b/src/lay/lay/layProgressWidget.cc index 09ce42b5a..7b924b1d4 100644 --- a/src/lay/lay/layProgressWidget.cc +++ b/src/lay/lay/layProgressWidget.cc @@ -43,7 +43,7 @@ public: QSize sizeHint () const { - return QSize (m_width, 1); + return QSize (m_width, 20); } QSize minimumSizeHint () const @@ -165,12 +165,16 @@ ProgressWidget::ProgressWidget (ProgressReporter *pr, QWidget *parent, bool full layout->addWidget (progress_bar_frame, 0, col, 1, 1); layout->setColumnStretch(col++, 2); - QHBoxLayout *pbf_layout = new QHBoxLayout (progress_bar_frame); + QVBoxLayout *pbf_layout = new QVBoxLayout (progress_bar_frame); progress_bar_frame->setLayout (pbf_layout); pbf_layout->setMargin (0); - mp_progress_bar = new ProgressBarWidget (progress_bar_frame); - pbf_layout->addWidget (mp_progress_bar); + mp_progress_bar1 = new ProgressBarWidget (progress_bar_frame); + pbf_layout->addWidget (mp_progress_bar1); + mp_progress_bar2 = new ProgressBarWidget (progress_bar_frame); + pbf_layout->addWidget (mp_progress_bar2); + mp_progress_bar3 = new ProgressBarWidget (progress_bar_frame); + pbf_layout->addWidget (mp_progress_bar3); layout->addItem (new QSpacerItem (8, 8, QSizePolicy::Fixed, QSizePolicy::Fixed), 0, col++, 1, 1); @@ -218,21 +222,38 @@ ProgressWidget::remove_widget () } void -ProgressWidget::set_can_cancel (bool f) +ProgressWidget::set_progress (tl::Progress *progress) { - mp_cancel_button->setEnabled (f); -} + bool can_cancel = false; + std::string text; -void -ProgressWidget::set_text (const std::string &text) -{ + if (progress) { + can_cancel = progress->can_cancel (); + text = progress->desc (); + } + + mp_cancel_button->setEnabled (can_cancel); mp_label->setText (tl::to_qstring (text)); -} -void -ProgressWidget::set_value (double v, const std::string &value) -{ - mp_progress_bar->set_value (v, value); + lay::ProgressBarWidget *progress_bars[] = { mp_progress_bar1, mp_progress_bar2, mp_progress_bar3 }; + + for (size_t i = 0; i < sizeof (progress_bars) / sizeof (progress_bars[0]); ++i) { + + lay::ProgressBarWidget *pb = progress_bars[i]; + pb->setVisible (progress != 0); + + if (progress) { + + std::string value = progress->formatted_value (); + double v = progress->value (); + pb->set_value (v, value); + + progress = progress->next (); + + } + + } + } void diff --git a/src/lay/lay/layProgressWidget.h b/src/lay/lay/layProgressWidget.h index 976e799fd..66446cea5 100644 --- a/src/lay/lay/layProgressWidget.h +++ b/src/lay/lay/layProgressWidget.h @@ -37,6 +37,11 @@ class QLabel; class QToolButton; class QGridLayout; +namespace tl +{ + class Progress; +} + namespace lay { @@ -50,9 +55,7 @@ Q_OBJECT public: ProgressWidget (ProgressReporter *pr, QWidget *parent, bool full_width = false); - void set_text (const std::string &text); - void set_value (double v, const std::string &value); - void set_can_cancel (bool f); + void set_progress (tl::Progress *progress); void add_widget (QWidget *widget); void remove_widget (); QWidget *get_widget () const; @@ -64,7 +67,7 @@ public slots: private: QLabel *mp_label; - ProgressBarWidget *mp_progress_bar; + ProgressBarWidget *mp_progress_bar1, *mp_progress_bar2, *mp_progress_bar3; QWidget *mp_widget; int m_widget_col; QGridLayout *mp_layout; diff --git a/src/tl/tl/tlProgress.cc b/src/tl/tl/tlProgress.cc index 4a8fbf85e..031bf22f7 100644 --- a/src/tl/tl/tlProgress.cc +++ b/src/tl/tl/tlProgress.cc @@ -148,8 +148,7 @@ Progress::set_desc (const std::string &d) } } -void -Progress::test (bool force_yield) +bool Progress::test(bool force_yield) { if (++m_interval_count >= m_yield_interval || force_yield) { @@ -180,6 +179,10 @@ Progress::test (bool force_yield) throw tl::BreakException (); } + return true; + + } else { + return false; } } @@ -222,8 +225,9 @@ RelativeProgress & RelativeProgress::set (size_t count, bool force_yield) { m_count = count; - test (force_yield || m_count - m_last_count >= m_unit); - m_last_count = m_count; + if (test (force_yield || m_count - m_last_count >= m_unit)) { + m_last_count = m_count; + } return *this; } diff --git a/src/tl/tl/tlProgress.h b/src/tl/tl/tlProgress.h index d5a3fb2b8..40323dd94 100644 --- a/src/tl/tl/tlProgress.h +++ b/src/tl/tl/tlProgress.h @@ -203,7 +203,7 @@ protected: * This method must be called by the derived class. * If "force_yield" is true, the events are always processed. */ - void test (bool force_yield = false); + bool test (bool force_yield = false); /** * @brief This method needs to be called by all derived classes after initialization has happened