Huge performance improvement for a specific array element interaction. Reason: duplicate cluster interactions spoiled performance.

This commit is contained in:
Matthias Koefferlein 2019-12-18 01:10:16 +01:00
parent fcba0018ba
commit 297f37a63a
6 changed files with 82 additions and 50 deletions

View File

@ -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<std::pair<ClusterInstance, ClusterInstance> >::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<std::pair<ClusterInstance, ClusterInstance> >::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<std::pair<ClusterInstance, ClusterInstance> > 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<std::pair<ClusterInstance, ClusterInstance> >::iterator i = cached.begin (); i != cached.end (); ++i) {
for (std::vector<std::pair<ClusterInstance, ClusterInstance> >::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 ());
}
/**

View File

@ -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 {

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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