Post #178,486
10/8/04 3:21:37 PM
10/8/04 3:22:09 PM
|
I am not saying it's shorter in C...
Let's try...
>>>>>>>>>>>>>>>>>>>>>>>> #include <iostream> #include <map> #include <vector> #include <string>
using namespace std;
int main(int argc, char **argv) { map<string, string> den;
den["one"] = "a"; den["two"] = "b"; den["three"] = "c"; den["four"] = "b"; den["five"] = "c"; den["six"] = "a"; den["seven"] = "b";
map<string, vector<string> > norm;
for (map<string, string>::iterator i = den.begin(); i != den.end(); i++) { string key = i->first; string value = i->second;
vector<string> listOfKeys = norm[value]; listOfKeys.push_back(key); norm[value] = listOfKeys; }
for (map<string, vector<string> >::iterator i = norm.begin(); i != norm.end(); i++) { cout << i->first << endl << " "; for (vector<string>::iterator j = i->second.begin(); j != i->second.end(); j++) { cout << *j << " "; } cout << endl; } }
<<<<<<<<<<<<<<<<<<<
The relevant code is 8 lines, and attrociously ineficient to boot. I can make it more efficient by storing pointer to vector instead of vector itself, but then it will be even longer, and bug-prone since I have to discard STL's memory management.
The reason for my comment is that I would have made all the same mistakes as Todd. You can see it in my C code. And the reason for *shudder* is really superluous - the syntax of @{...} to access a value in a hash by reference. Mind you, there is no nice way to do it in STL either...
I guess Perl's ability to just do what I mean in some cases, and require really arcane syntax to do obvious things in others throws me off. I haven't developed the "Perl Sense" that would tell me when the context is right, and when it isn't. Yes, it simply means that I am not a Perl programmer. Guilty as charged.
--
... a reference to Presidente Arbusto. -- [link|http://itre.cis.upenn.edu/~myl/languagelog/archives/001417.html|Geoffrey K. Pullum]
Edited by Arkadiy
Oct. 8, 2004, 03:22:09 PM EDT
I am not saying it's shorted in C...
Let's try...
>>>>>>>>>>>>>>>>>>>>>>>> #include <iostream> #include <map> #include <vector> #include <string>
using namespace std;
int main(int argc, char **argv) { map<string, string> den;
den["one"] = "a"; den["two"] = "b"; den["three"] = "c"; den["four"] = "b"; den["five"] = "c"; den["six"] = "a"; den["seven"] = "b"; map<string, vector<string> > norm;
for (map<string, string>::iterator i = den.begin(); i != den.end(); i++) { string key = i->first; string value = i->second;
vector<string> listOfKeys = norm[value]; listOfKeys.push_back(key); norm[value] = listOfKeys; }
for (map<string, vector<string> >::iterator i = norm.begin(); i != norm.end(); i++) { cout << i->first << endl << " "; for (vector<string>::iterator j = i->second.begin(); j != i->second.end(); j++) { cout << *j << " "; } cout << endl; } }
<<<<<<<<<<<<<<<<<<<
The relevant code is 8 lines, and attrociously ineficient to boot. I can make it more efficient by storing pointer to vector instead of vector itself, but then it will be even longer, and bug-prone since I have to discard STL's memory management.
The reason for my comment is that I would have made all the same mistakes as Todd. You can see it in my C code. And the reason for *shudder* is really superluous - the syntax of @{...} to access a value in a hash by reference. Mind you, there is no nice way to do it in STL either...
I guess Perl's ability to just do what I mean in some cases, and require really arcane syntax to do obvious things in others throws me off. I haven't developed the "Perl Sense" that would tell me when the context is right, and when it isn't. Yes, it simply means that I am not a Perl programmer. Guilty as charged.
--
... a reference to Presidente Arbusto. -- [link|http://itre.cis.upenn.edu/~myl/languagelog/archives/001417.html|Geoffrey K. Pullum]
|
Post #178,487
10/8/04 3:34:09 PM
|
And now for my real comment
If someone didn't know any of the STL stuff that you used, but had some half-understood samples around to start with and flailed around for a while until giving up, what would the final result look like? What would that code do?
I don't think that Todd's attempt was particularly unreasonable given where he is in Perl. I also don't think that you should judge what Perl is like to use based on it. I furthermore submit that if you judged the language that you mostly use by how you were judging Perl (ie how badly a beginner in that language can thrash around without making progress), it would come out sucking just as badly.
No, you're not a Perl programmer. Which is fine. But until you care to learn the language, please don't throw out gratuitous insults.
Thank you, Ben
I have come to believe that idealism without discipline is a quick road to disaster, while discipline without idealism is pointless. -- Aaron Ward (my brother)
|
Post #178,489
10/8/04 3:47:36 PM
|
May be it's a hindsight thing
but it seems to me that it took me less time and less effort to understand C, C++ and STL that it takes me to understand Perl. My "*shudder*" was not based on Todd's code, but rather on your code. As you say yourself, in Perl you have to be aware of the context at all times, and it's hard to stay aware because most of the time it "just works". In C++ I don't have such problem. May be because it became a second nature to me so long ago. Then again, in Smalltalk, I don't have such problem either. Probably because those languages don't try to magically do what I mean in most cases.
--
... a reference to Presidente Arbusto. -- [link|http://itre.cis.upenn.edu/~myl/languagelog/archives/001417.html|Geoffrey K. Pullum]
|
Post #178,520
10/8/04 6:13:45 PM
|
It could be many things
I know that when I learned to program in Perl, the course seemed much smoother than when I set out to learn other languages later. But then I realized that there were several factors: - I misremember how long I took to learn Perl. It feels like I picked up the book and was writing it fluently a few weeks later. But I know that there were important parts of the language that I learned a lot later.
- When I was a baby in Perl, I tried to do baby-like things with it and succeeded. Now when I look at new languages, I over-reach. I immediately try to do things that I know how to do in Perl, and don't know enough to do them.
- When I learned Perl there was a constant feeling of accomplishment because I didn't know any way to easily do what I just learned. In other languages that sense is gone because whatever I just learned, I already knew how to do.
As for context, I think that it is important to know about context, but ideally it sinks into being a reflex. It's handled by the same part of your brain that handles grammar and knows when, for instance, you have to switch from past to present to future tense. Certainly I am not conciously aware of thinking about context, though I can tell you what is going on with it at any given moment. Cheers, Ben
I have come to believe that idealism without discipline is a quick road to disaster, while discipline without idealism is pointless. -- Aaron Ward (my brother)
|
Post #178,581
10/9/04 12:22:32 AM
|
I don't know - multimap
as I read through the example, I could see why he went from a hash to a hash of arrays -- perl dosn't really have a multimap facility that I know of.
As I looked at with C++ & STL; I thought, why are we putting it in an array at all?
#include <iostream> #include <map> #include <vector> #include <string> int main(int argc, char **argv) { std::map<std::string, std::string> den; den["one"] = "a"; den["two"] = "b"; den["three"] = "c"; den["four"] = "b"; den["five"] = "c"; den["six"] = "a"; den["seven"] = "b"; std::multimap<std::string , std::string> norm; for (std::map<std::string, std::string>::iterator i = den.begin(); i != den.end(); i++) { norm.insert(std::pair<std::string, std::string>(i->second, i->first)); } std::string s; std::multimap<std::string, std::string>::iterator pos; for (std::multimap<std::string, std::string >::iterator i = norm.begin(); i != norm.end(); i++) { if (s != i->first) { s = i->first; std::cout << i->first << ":"; for (pos = norm.lower_bound(i->first); pos != norm.upper_bound(i->first); ++pos) { std::cout << pos->second << " "; } std::cout << std::endl; } } std::cout << std::endl; }
I'll admit a lot of wasted effort for the formatted output. But, given the times for data lookup...
|
Post #178,606
10/9/04 12:17:47 PM
|
Re: I don't know - multimap
I thought about it, but then decided to stay true to the original format. May be Todd wanted to do something with arrays later... Your version is more efficient, too.
--
... a reference to Presidente Arbusto. -- [link|http://itre.cis.upenn.edu/~myl/languagelog/archives/001417.html|Geoffrey K. Pullum]
|
Post #178,607
10/9/04 12:25:52 PM
|
Why the worry about efficiency?
You're comparing with Perl. Pretty much anything is at least 10x faster in C than Perl. Any semi-sane C++ version will be faster. And take less memory. If programmer time is less important than those factors, then Perl is definitely the wrong language.
Furthermore standard programming advice - which I follow even in Perl - is to not micro-optimize. Concentrate on making the design clean, and if performance is a problem later (it usually isn't), then benchmark for the hotspots and optimize that. Always thinking about efficiency looks a heck of a lot like micro-optimizing to me.
Cheers, Ben
I have come to believe that idealism without discipline is a quick road to disaster, while discipline without idealism is pointless. -- Aaron Ward (my brother)
|
Post #178,608
10/9/04 12:30:44 PM
|
I worry about efficiency
because I deliberately picked O(n^2) that looks clean to someone who doesn't care to go into STL's intricacies. I could have gotten O(n log n). I think it's a good trade-off for a sample code, but I am used to be aware of such trade-offs. AT the level I usually program, that kind of decision is a difference between 12,000 traps per second and 4,000 traps per second.
--
... a reference to Presidente Arbusto. -- [link|http://itre.cis.upenn.edu/~myl/languagelog/archives/001417.html|Geoffrey K. Pullum]
|
Post #178,612
10/9/04 12:59:07 PM
|
Ah
Yeah, I tend to be aware of O(n) vs O(n*log(n)). If my data set is small I might go for the worse one, but might not.
One nice thing about Perl is that often the most obvious way to write something is also pretty good algorithmically. That is because you reach for hashes early, which have average performance O(1). (Worst case O(n), I've never seen that happen accidentally though...)
So the Perl solution offered is O(n) average case, with an unlikely worst case performance of O(n^2).
Cheers, Ben
I have come to believe that idealism without discipline is a quick road to disaster, while discipline without idealism is pointless. -- Aaron Ward (my brother)
|
Post #178,610
10/9/04 12:41:13 PM
|
C vs Perl - efficiency - untrue for me
I'm almost always bottlenecked on IO. Well, maybe not any more with the new arrays. But for my type of data munging for data warehouse work, Perl has been a fast as C when I did my simple tests.
|
Post #178,613
10/9/04 1:11:47 PM
|
Point - but you may want to rebenchmark
I know that historically on Linux, Perl's I/O performance was not up to snuff. I don't remember the exact cause, but the situation was bad enough that with a default compile it could be faster to read data and split it into lines inside of Perl rather than have Perl do that splitting!
I believe that this has since been fixed.
Another vague memory tells me that enabling Unicode processing can add significant overhead to Perl's I/O.
And, of course, the default Perl 5.8 that shipped with Red Hat 9 was compiled with threads and significantly underperformed any version of Perl that you'd be likely to compile for yourself. People benchmarking that gave rise to a myth that Perl 5.8 was a lot slower than 5.6. Nope. If you compile with the same options, the speeds are basically equivalent. But the version of 5.8 shipped by Red Hat was slower than their version of 5.6. Here are [link|http://mathforum.org/epigone/modperl/clikingspimp/1068515972.2699.131.camel@localhost.localdomain|some benchmarks] that a friend of mine did.
Cheers, Ben
I have come to believe that idealism without discipline is a quick road to disaster, while discipline without idealism is pointless. -- Aaron Ward (my brother)
|