Performance question


#1

Hi, can someone please tell me why the second method is faster than the first one?
the second method was about 1.5 times faster than the first one to execute.
So I’m just curious what makes the first one slower than the second.

void ofApp::getBoundingBoxDimen1(float &boxWidth, float &boxHeight, const vector<ofVec3f> &vertices) {
    
    auto xExtremes = minmax_element(vertices.begin(), vertices.end(),
                                    [](const ofVec3f& lhs, const ofVec3f& rhs) {
                                        return lhs.x < rhs.x;
                                    });
    auto yExtremes = minmax_element(vertices.begin(), vertices.end(),
                                    [](const ofVec3f& lhs, const ofVec3f& rhs) {
                                        return lhs.y < rhs.y;
                                    });
    boxWidth = xExtremes.second->x - xExtremes.first->x;
    boxHeight = yExtremes.second->y - yExtremes.first->y;
}

void ofApp::getBoundingBoxDimen2(float &boxWidth, float &boxHeight, const vector<ofVec3f> &vertices) {
    
    ofRectangle box;
    
    for(size_t i=0; i<vertices.size(); ++i) {
        
        if(i == 0) {
            box.set(vertices[i],0,0);
        } else {
            box.growToInclude(vertices[i]);
        }
    }
    boxWidth = box.width;
    boxHeight = box.height;
}

#2

are you running in release?


#3

also looking at your code closer, the first method is doing two iterations while the second is doing only one


#4

No, the test was based on debug mode. If I run in release mode, the second method was only slightly faster than the first one.

I just wanted to know the best algorithm to calculate dimensions of 3d bounding box based on the vertices.

I decided to calculate width, height using the second method, and additionally calculate depth using the first method. so it can perform 2 iterations total.

Thanks @arturo


#5

Maybe something in this direction could be faster? (untested)

void ofApp::getBoundingBoxDimen3(ofVec3f &size, const vector<ofVec3f> &vertices) {
    ofVec3f bbmin {vertices[0]};
    ofVec3f bbmax {vertices[0]};
    for(auto &v : vertices) {   
        if(v.x < bbmin.x) bbmin.x = v.x;
        if(v.y < bbmin.y) bbmin.y = v.y;
        if(v.z < bbmin.z) bbmin.z = v.z;
        if(v.x > bbmax.x) bbmax.x = v.x;
        if(v.y > bbmax.y) bbmax.y = v.y;
        if(v.z > bbmax.z) bbmax.z = v.z;
    }
    size = bbmax - bbmin;
}

You could then access the .x, .y and .z properties of the size object. I think it might be faster because it doesn’t call any functions. If you try it I would be curious about the speed difference :slight_smile:


#6

you should do any kind of performace test in release, mimax_element and similar functions do a function call per iteration but that function call disappears in release.


#7

Hey @hamoid

I tested your version and it was about two times faster than the second code.
Thank you very much! :slight_smile: