Re^2: Perl vs C
by JavaFan (Canon) on Mar 14, 2009 at 14:37 UTC
|
Coding effiency is about 5-10x.
Interesting. Someone quantized the coding efficiency. Where do you get the numbers from? Are you quoting a paper? Or did you make them up?
One fundamental roadblock to good Perl is mis-understanding of Perl lists
And the most fundamental part of it is not grasping the difference between a list and an array. Which you don't seem to do if I read your post.
There is no need for a "linked list" in Perl! A Perl list does what a C linked list can do and more!
There's no "need" for a linked list in C either. Anything done with a linked list can be done in another way in C as well.
Having said that, one of the attractive things of a linked list is it's O(1) removal of a element (assuming you have a pointer to it). Sure you can delete an element from an Perl array (I think you meant Perl array where you wrote Perl list) - but splicing out an element from an array in Perl takes time linear to the distance of the element to an end of the array (so, linear worst case). Also, adding to a linked list (whether in the middle or the end) is always O(1). But not with Perl arrays (not even when adding at the end - it often can be done in O(1), but if perl needs to realloc the space used for the array, it takes a linear amount of time).
Considering that people already have take a huge speed and memory hit when picking Perl over C, and that computers nowadays are much faster and have more memory than 30 years ago, and typically write deletion statements that need to scan the array anyway (@arr = grep {...} @arr), you don't see many linked lists in Perl.
So you should think of a Perl list more like a C linked list.
I think that's a very bad advice. It doesn't do justice to Perl arrays (nor lists), and Perl arrays/lists don't deliver the good features linked lists have.
| [reply] [d/l] |
|
|
While I suspect that you were not responding to the most informed person in the world, I am willing to back up some of what he said.
According to Code Complete 2, a number of studies have shown that, to a good approximation, the amount of code written per day in a programming language is independent of how high level that programming language is. Therefore you can estimate the productivity of people working in that language from the efficiency of saying things in that language. With that in mind he produces a chart of, based on real world code bases, the approximate relative number of statements needed in different languages to say the same thing.
By his figures, Perl is 6 times as efficient to say things in as C, which is within the 5-10x estimate that Marshall gave. Incidentally by his figures, Java is 2.5x as efficient as C, which would make Perl over twice as efficient to code in as Java.
About linked lists, one of the most common use cases for linked lists in C is that someone wants a queue or a stack which can grow arbitrarily without having to know the size first. For that use case, Perl arrays are a great replacement. For the case where you wish to insert or delete in the middle of an array, it is true that a linked list written in Perl scales better than using splice. But the overhead of Perl is so much that if your arrays only have hundreds of elements in it, the simple splice solution is more efficient than writing a linked list. (There is even more overhead if you want to keep your double-linked lists from leaking memory.)
So while Perl arrays are theoretically not replacements for linked lists, for a great many practical purposes they are.
| [reply] |
|
|
I would have said that functionally, a linked list is more like a hash than an array, so the argument seems prone to falling off a cliff and accelerating exponentially as it enjoys the gravity.
An irony might be that I would bet that perl hashes are implimented via C pointer arrays (just a guess).
Another guess: 6X is bang on, bytes of code wise (but how long you took with each line may be another thing?...the only real "efficiency" may be comprehensibility, which should have to be wildly Subject-Oriented)
| [reply] |
|
|
|
|
|
|
|
|
|
The Perl coding efficiency is obvious. If you think that it is only like 2-3x, fine with me. From the code that I've written in Perl, I figure that it is more than that. But I would agree with a >= 2x number. So done point! The difference is so enormous I won't squabble about a minor factor of 2x.
No, I didn't mean Perl array. I meant Perl list. Please explain what you think the difference is between a Perl array and a Perl List. I think this just some kind of nomenclature difference.. Not any real disagreement!
Maintenance of a Perl "list" is expensive CPU wise and I didn't say that it wasn't.
@arr = grep {...} @arr is essentially a scan of of what would be in C linked list, but as I said, even more powerful from a language standpoint.
Update: I am still not "getting it". A simple Perl list is similar to a C char ** array (array of pointers of pointers to strings), but more flexible and more powerful.
| [reply] |
|
|
Please explain what you think the difference is between a Perl array and a Perl List.
When someone talks of lists in Perl, they are usually talking about one of the following:
- A list of values on the stack.
- The n-ary operator which creates a list on the stack. (e.g. "EXPR, EXPR, EXPR")
There is also "list context", a context in which expressions can be evaluated.
In contrast, an array is a type of variable. There is no list variable type.
I'd be hard pressed to find similarities between list values, list operators, list context and array variables because values, operators, contexts and variables are fundamentally different from each other. It's not just nomenclature.
I am still not "getting it". A simple Perl list is similar to a C char ** array
A Perl array is similar to T* array in C, except it automatically resizes itself when needed (like C++'s std::vector). Due to C's type system, C doesn't have anything similar to Perl lists. (Same goes for C++.)
| [reply] [d/l] [select] |
|
|
|
|
|
|
|
|
|
Please explain what you think the difference is between a Perl array and a Perl List.
Arrays are variables, lists are values. It's the same difference as between $foo and 3.
I think this just some kind of nomenclature difference.. Not any real disagreement!
Differences in nomenclature are not something to trivialize - specially not when it's about important concepts.
A simple Perl list is similar to a C char ** array (array of pointers of pointers to strings)
No, it's not. First of all, a char is not a string, but a (small) integer. Depending on usage, a C char is equivalent to a Perl integer, or a Perl string consisting of exactly one character. Secondly, in C, array elements all have the same size - all elements are integers, characters or pointers for instance. (Pointers in your example). In Perl, values of a list can have different "sizes" - or rather, different types (mixed integers, references, objects, strings, etc) - as the "size" of a value isn't a useful concept in Perl (it is in perl, but not in Perl). Third, and this is the big one, elements of an array may change (both in C and in Perl). But in Perl, lists are unmutable (of course they can be changed by perl, or by using XS - but not from a Perl POV). They are as unmutable as the value 3.
| [reply] [d/l] [select] |
|
|
|
|
|
Re^2: Perl vs C
by Porculus (Hermit) on Mar 14, 2009 at 19:33 UTC
|
There is no need for a "linked list" in Perl! A Perl list does what a C linked list can do and more! Fond as I am of shiftily pushing and popping in Perl, I simply have to disagree with this.
For example, one nice property of a linked list that isn't shared by what you call Perl lists is that pointers into it are not invalidated by insert/delete operations elsewhere.
(This is actually a real-world example that has bitten me just this week: I have a list of properties, and a bunch of objects that each need to access all properties up to and including a certain point. The implementation stores the properties in an array and simply has the objects hold the index of the last property they need. Now suddenly I have a new requirement to insert properties at arbitrary positions in the list, and that means I potentially have to change the indices stored by every object. If I'd been using a linked list, I'd have got the correct behaviour by default. I'm sorely tempted to redo it that way ...)
| [reply] |
|
|
That depends on how you define "pointers."
If you're simply doing Node* n = ¤tNode; in C, then that works fine in perl, too: my $ref = \$list[$n];. Now, granted, in C, you know what's next and what's before (assuming doubly-linked), but I have to admit to not needing that very often. And, besides, you can create a linked list in Perl, too, if that's what you really want. Each node is just an array, where the first element (0) is a reference to the data, the second is a reference to the previous node, and the third is a reference to the next node.
If, however, your pointer in Perl is an index, well, yes, that's silly. You don't take an index of your linked list in C, so comparing them isn't quite fair. Of course, if you're using a STL linked list, then you can take an index, but you don't. Well, not if you expect it to survive insert/delete operations elsewhere.
Like I said, I don't find the need for surviving insert/delete operations too often. I usually use map to transform list A to list B, and survivability is moot. Generally, my object is either transforming a list (usually via map), or my object cares about a particular value/object (which I can retain via reference or copy, as is appropriate). Doing both at the same time is pretty rare. I suppose I've just changed my thinking ("paradigm shift") to fit idiomatic perl. Works for me and my little projects ;-)
| [reply] [d/l] [select] |