mirror of https://github.com/KLayout/klayout.git
Huge performance improvement for a specific array element interaction. Reason: duplicate cluster interactions spoiled performance.
This commit is contained in:
parent
fcba0018ba
commit
297f37a63a
|
|
@ -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 ());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue