Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I'm working on a project right now where we're replacing a Qt interface written in Python (PyQt) with C++ Qt as it's way too slow (interface is really laggy), and other than things like having to occasionally delete objects manually (often, if you just add a widget to a layout, Qt does the deletion for you), it's pretty much a 1-1 mapping.

We're also replacing core op-graph and geometry processing from Python to C++, and again it's close to 1-1 - there's a bit of overhead in the loops - in our coding style we're caching begin iterators on the line before the loop, but other than that it's very close.

And the speed of the app is so much faster it's not even funny.



>in our coding style we're caching begin iterators on the line before the loop

Can you give an example of what this looks like?


  python:

  for face in mesh.faces():
  	faceCentre = Point()
  	for v in face.vertices():
  		faceCentre.add(mesh.getPoint(v))
  	faceCentre.div(len(face.vertices()))
  
  C++:
  
  std::vector<Face>::const_iterator itFace = mesh.getFaces().begin();
  for (; itFace != mesh.getFaces().end(); ++itFace)
  {
        const Face& face = *itFace;
  	Point faceCentre;
  	std::vector<unsigned int>::const_iterator itVertex = face.vertices.begin();
  	for (; itVertex != face.vertices().end(); ++itVertex)
  	{
  		const unsigned int& pointIndex = *itVertex;
  		faceCentre += mesh.getPoint(pointIndex);
  	}
  	faceCentre /= (float)face.vertices().size();
  }
So the C++ is longer, but you've got braces, and the references to the Face and unsigned int pointIndex are placed as a local variables, which makes debugging much easier - they could be inlined.

It's possible to get that down even more using more modern C++ - using auto variables and not declaring the start iterator on it's own line.

So yes, counting braces, it can be a lot more lines, but if you don't count braces, it's generally not that much more.


I guess what I'm asking is, why are you declaring the start iterator on its own line? What benefit does it have? Or does is just make the for loop line shorter?

Also, as of C++11 you can do this:

  for(const Face& face : mesh.getFaces()) {
  	Point faceCentre;
  	for(size_t pointIndex : face.vertices())
  		faceCentre += mesh.getPoint(pointIndex);
  	faceCentre /= static_cast<float>(face.vertices().size());
  }


Yeah, it makes the for line shorter.

We sometimes hoist the end iterator as well, as often g++ can't optimise out the call to .end() each iteration - it can if there's a ref to a const item and you call end() on that const ref, but otherwise, it generally doesn't as it can't guarantee the item hasn't been modified.

We're still stuck with CentOS 5.4, so g++ 4.1 for us as that's what we've got to deploy to (although we use ICC for production builds, building off the g++ 4.1 standard headers)...

Basically, we want top possible speed - if that means the code's a bit more verbose than it can be, so be it.


That's 163 vs 486 characters, so, as I expected you'd need about three times the amount of code to do the same thing in C++.

And just look at the difference in readability/simplicity. I can explain the Python code to my 12 year-old cousin, the C++ version though...




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: