Mij lijkt het dat die range/set functies een hele hoop geheugen gaan alloceren, iets wat je ook met een eenvoudige if-test kan doen.
Als b[0] of b[1] tussen a[0] en a[1] ligt, is er een overlap.
Verder kan je wat optimalizeren door sum() te gebruiken (wat native loops gebruikt ipv Python loops):
def overlap(a, b):
return a[0] < b[0] < a[1] || a[0] < b[1] < b[2]
for aitem in a:
teller += sum(1 if overlap(aitem, bitem) else 0 for bitem in b)
Mocht dat nog te traag zijn, kan je eens kijken naar numpy, of de boel in C(++) implementeren:
vector<pair<int,int>> a = {{1,5},{10,13},{20,25}};
vector<pair<int,int>> b= {{4,8},{30,33},{41,50},{15,20}}
auto _overlap = [](const pair<int,int>& p1, const pair<int,int>& p2) {
return (a[0] < b[0] && b[0] < a[1]) || (a[0] < b[1] && b[1] < b[2]);
};
unsigned counter = 0;
for(auto& aitem : a) {
counter += count_if(b.begin(), b.end(), [&](const pair<int,int>& bitem) { return _overlap(aitem, bitem); });
}
Je kan dat laatste ook eenvoudig parallelizeren (hier over 4 threads):
for(auto it = a.begin(); it != a.end(); ++it) {
auto f1 = async(launch::async, [&] {
return count_if(b.begin(), b.end(), [&](const pair<int,int>& bitem) {
return _overlap(*a++, bitem);
});
});
auto f2 = async(launch::async, [&] {
return count_if(b.begin(), b.end(), [&](const pair<int,int>& bitem) {
return _overlap(*a++, bitem);
});
});
auto f3 = async(launch::async, [&] {
return count_if(b.begin(), b.end(), [&](const pair<int,int>& bitem) {
return _overlap(*a++, bitem);
});
});
auto f4 = async(launch::async, [&] {
return count_if(b.begin(), b.end(), [&](const pair<int,int>& bitem) {
return _overlap(*a++, bitem);
});
});
counter += f1.get() + f2.get() + f3.get() + f4.get();
}