"Whenever possible, we use Python"
"When necessary, we use C++"
"As of right now, it ends up that about 75% of our code is C++ and 17% is Python (link) since it turns out that a lot of BIND 10 is performance-critical."
"Whenever possible, we use Python"
"When necessary, we use C++"
"As of right now, it ends up that about 75% of our code is C++ and 17% is Python (link) since it turns out that a lot of BIND 10 is performance-critical."
Adding to this, the fact that BIND is something pretty performance-intensive, I don't think this makes it look bad at all.
This also clashes with the belief in the Python community that performance is not an issue because you just rewrite those few critical sections in C/C++. How's 75% as one possible definition of "few"?
As another comment puts it: How much more C++ would there be without python?
Of the total code of a very specific application, with very specific performance needs.
For others applications, including servers, the ratio could vary widely.
The percentages may or may not be simply a case of C++ verbosity, but without actually browsing the source, we shouldn't jump the gun on exactly what percentage of "heavy lifting" C++ is doing vs. Python.
Because it directly contradicts the "only 20% of your code is performance sensitive and the other 80% can be scripting language X" nonsense that scripting language apologists constantly parrot with no evidence. This is a good example of how scripting languages are in fact not well suited to application development, and should instead be used for scripting.
To put it more concisely: "only 20% of your logic is performance sensitive and the other 80% can be encoded in scripting language X leading to a significant reduction of your total code."
Expansion Expanded 1 to 1: 75/ 17 --> 75% 17% 1 to 3: 75/ 51 --> 56% 38% 1 to 5: 75/ 85 --> 45% 51% 1 to 10: 75/170 --> 30% 67%
The LOC doesn't measure how many features are implemented in each language. If a language is more verbose or need more detailed management the same features will appear to be longer.
Several boost libraries are inspired by python and C++11 features all help to write C++ code that is surprisingly similar to python, with a bit of extra type sepcification. If you think otherwise I'd suggest you're probably thinking of the C++ of the 90s - a more C with classes, and not modern C++.
I often find it useful to develop and prototype in python and convert to C++. Most often I'm doing this because my python simulations can take days and the C++ versions hours. Often I find it is not just the performance critical areas, but it is easy enough just to wholesale convert the lot.
I agree, especially with C++11 and (besides Boost) Qt. It's often the header/code separation that makes things a bit tedious, having to keep function and method signatures in-sync. Of course, if you are template-land that is not that much of a problem.
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.
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.
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());
}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.
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...
What I'm saying is that "amount of code" is not a valid magnitude when comparing different languages.
In my experience converting some unmaintained Perl tools to Python, the Python version was almost as long as the Perl one, but it included more functionality, comments and error handling (I'm not criticising Perl here but the unmaintained code that I had to convert).
(And as others have said, 17% of LOC in Python might still mean majority of the functionality in Python).
(https://plus.google.com/115212051037621986145/posts/HajXHPGN...)