mirror of https://github.com/KLayout/klayout.git
Some performance improvement by eliminating empty objects in the box scanner.
This commit is contained in:
parent
f83e1dae43
commit
d79a448eaa
|
|
@ -273,6 +273,25 @@ public:
|
||||||
typedef bs_side_compare_vs_const_func<BoxConvert, Obj, Prop, box_top<Box> > below_func;
|
typedef bs_side_compare_vs_const_func<BoxConvert, Obj, Prop, box_top<Box> > below_func;
|
||||||
typedef bs_side_compare_vs_const_func<BoxConvert, Obj, Prop, box_right<Box> > left_func;
|
typedef bs_side_compare_vs_const_func<BoxConvert, Obj, Prop, box_right<Box> > left_func;
|
||||||
|
|
||||||
|
// sort out the entries with an empty bbox (we must not put that into sort)
|
||||||
|
|
||||||
|
typename container_type::iterator wi = m_pp.begin ();
|
||||||
|
for (typename container_type::iterator ri = m_pp.begin (); ri != m_pp.end (); ++ri) {
|
||||||
|
if (! bc (*ri->first).empty ()) {
|
||||||
|
if (wi != ri) {
|
||||||
|
*wi = *ri;
|
||||||
|
}
|
||||||
|
++wi;
|
||||||
|
} else {
|
||||||
|
// we call finish on empty elements though
|
||||||
|
rec.finish (ri->first, ri->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wi != m_pp.end ()) {
|
||||||
|
m_pp.erase (wi, m_pp.end ());
|
||||||
|
}
|
||||||
|
|
||||||
if (m_pp.size () <= m_scanner_thr) {
|
if (m_pp.size () <= m_scanner_thr) {
|
||||||
|
|
||||||
// below m_scanner_thr elements use the brute force approach which is faster in that case
|
// below m_scanner_thr elements use the brute force approach which is faster in that case
|
||||||
|
|
@ -606,6 +625,42 @@ public:
|
||||||
typedef bs_side_compare_vs_const_func<BoxConvert2, Obj2, Prop2, box_top<Box> > below_func2;
|
typedef bs_side_compare_vs_const_func<BoxConvert2, Obj2, Prop2, box_top<Box> > below_func2;
|
||||||
typedef bs_side_compare_vs_const_func<BoxConvert2, Obj2, Prop2, box_right<Box> > left_func2;
|
typedef bs_side_compare_vs_const_func<BoxConvert2, Obj2, Prop2, box_right<Box> > left_func2;
|
||||||
|
|
||||||
|
// sort out the entries with an empty bbox (we must not put that into sort)
|
||||||
|
|
||||||
|
typename container_type1::iterator wi1 = m_pp1.begin ();
|
||||||
|
for (typename container_type1::iterator ri1 = m_pp1.begin (); ri1 != m_pp1.end (); ++ri1) {
|
||||||
|
if (! bc1 (*ri1->first).empty ()) {
|
||||||
|
if (wi1 != ri1) {
|
||||||
|
*wi1 = *ri1;
|
||||||
|
}
|
||||||
|
++wi1;
|
||||||
|
} else {
|
||||||
|
// we call finish on empty elements though
|
||||||
|
rec.finish1 (ri1->first, ri1->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wi1 != m_pp1.end ()) {
|
||||||
|
m_pp1.erase (wi1, m_pp1.end ());
|
||||||
|
}
|
||||||
|
|
||||||
|
typename container_type2::iterator wi2 = m_pp2.begin ();
|
||||||
|
for (typename container_type2::iterator ri2 = m_pp2.begin (); ri2 != m_pp2.end (); ++ri2) {
|
||||||
|
if (! bc2 (*ri2->first).empty ()) {
|
||||||
|
if (wi2 != ri2) {
|
||||||
|
*wi2 = *ri2;
|
||||||
|
}
|
||||||
|
++wi2;
|
||||||
|
} else {
|
||||||
|
// we call finish on empty elements though
|
||||||
|
rec.finish2 (ri2->first, ri2->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wi2 != m_pp2.end ()) {
|
||||||
|
m_pp2.erase (wi2, m_pp2.end ());
|
||||||
|
}
|
||||||
|
|
||||||
if (m_pp1.empty () || m_pp2.empty ()) {
|
if (m_pp1.empty () || m_pp2.empty ()) {
|
||||||
|
|
||||||
// trivial case
|
// trivial case
|
||||||
|
|
|
||||||
|
|
@ -283,6 +283,28 @@ TEST(1f)
|
||||||
EXPECT_EQ (tr.str, "");
|
EXPECT_EQ (tr.str, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(1g)
|
||||||
|
{
|
||||||
|
// empty elements
|
||||||
|
db::box_scanner<db::Box, size_t> bs;
|
||||||
|
|
||||||
|
std::vector<db::Box> bb;
|
||||||
|
bb.push_back (db::Box (0, 0, 101, 100));
|
||||||
|
bb.push_back (db::Box (200, 0, 300, 100));
|
||||||
|
bb.push_back (db::Box ());
|
||||||
|
bb.push_back (db::Box (100, 0, 200, 100));
|
||||||
|
bb.push_back (db::Box ());
|
||||||
|
for (std::vector<db::Box>::const_iterator b = bb.begin (); b != bb.end (); ++b) {
|
||||||
|
bs.insert (&*b, b - bb.begin ());
|
||||||
|
}
|
||||||
|
|
||||||
|
BoxScannerTestRecorder tr;
|
||||||
|
bs.set_fill_factor (0.0);
|
||||||
|
db::box_convert<db::Box> bc;
|
||||||
|
bs.process (tr, 0, bc);
|
||||||
|
EXPECT_EQ (tr.str, "<2><4>(0-3)<0><1><3>");
|
||||||
|
}
|
||||||
|
|
||||||
void run_test2 (tl::TestBase *_this, size_t n, double ff, db::Coord spread, bool touch = true)
|
void run_test2 (tl::TestBase *_this, size_t n, double ff, db::Coord spread, bool touch = true)
|
||||||
{
|
{
|
||||||
std::vector<db::Box> bb;
|
std::vector<db::Box> bb;
|
||||||
|
|
@ -985,6 +1007,37 @@ TEST(two_1b)
|
||||||
EXPECT_EQ (trstop.str, "(1-12)");
|
EXPECT_EQ (trstop.str, "(1-12)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(two_1c)
|
||||||
|
{
|
||||||
|
// some empty elements
|
||||||
|
db::box_scanner2<db::Box, size_t, db::SimplePolygon, int> bs;
|
||||||
|
|
||||||
|
std::vector<db::Box> bb;
|
||||||
|
bb.push_back (db::Box ());
|
||||||
|
bb.push_back (db::Box (0, 0, 100, 100));
|
||||||
|
bb.push_back (db::Box (100, 10, 200, 110));
|
||||||
|
|
||||||
|
std::vector<db::SimplePolygon> bb2;
|
||||||
|
bb2.push_back (db::SimplePolygon (db::Box ()));
|
||||||
|
bb2.push_back (db::SimplePolygon (db::Box (50, 50, 150, 150)));
|
||||||
|
bb2.push_back (db::SimplePolygon (db::Box (10, 10, 110, 110)));
|
||||||
|
|
||||||
|
for (std::vector<db::Box>::const_iterator b = bb.begin (); b != bb.end (); ++b) {
|
||||||
|
bs.insert1 (&*b, b - bb.begin ());
|
||||||
|
}
|
||||||
|
for (std::vector<db::SimplePolygon>::const_iterator b = bb2.begin (); b != bb2.end (); ++b) {
|
||||||
|
bs.insert2 (&*b, int (b - bb2.begin ()) + 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
BoxScannerTestRecorderTwo tr;
|
||||||
|
bs.set_fill_factor (0.0);
|
||||||
|
db::box_convert<db::Box> bc1;
|
||||||
|
db::box_convert<db::SimplePolygon> bc2;
|
||||||
|
bs.set_scanner_threshold (0);
|
||||||
|
EXPECT_EQ (bs.process (tr, 1, bc1, bc2), true);
|
||||||
|
EXPECT_EQ (tr.str, "<0><10>(1-12)(2-12)(1-11)(2-11)<1><2><12><11>");
|
||||||
|
}
|
||||||
|
|
||||||
void run_test2_two (tl::TestBase *_this, size_t n, double ff, db::Coord spread, bool touch = true)
|
void run_test2_two (tl::TestBase *_this, size_t n, double ff, db::Coord spread, bool touch = true)
|
||||||
{
|
{
|
||||||
std::vector<db::Box> bb;
|
std::vector<db::Box> bb;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue