Hacker News new | past | comments | ask | show | jobs | submit login

> The cost of inefficient code can be higher than you think. Efficient code stretches hardware further, reduces power usage, makes code easier for programmers to understand.

I'm curious what the reasoning is for "Efficient code ... makes code easier for programmers to understand". To my mind, efficient code (in this case, I assume coding to the hardware, as they mention elsewhere), has many benefits, but making it easier to understand is not one of them. A useful comment by the code may help, but that's not a result of efficient coding, that's a result of good commenting practice.




In complex systems low-level efficiency is far less beneficial than high-level efficiency. To achieve high-level efficiency you need to have a clear understanding of how the system works as a whole. That is impossible is the code is unintelligible bag of tricks.

I've seen this a lot when working in PHP. I wrote some websites from ground-up (using something similar to my own framework). I optimized int multiple times to great results. The biggest benefits didn't come from making a particular function faster, they came from realizations that large chunks of complexity in templating, routing and permissions checking subsystems simply weren't necessary. It doesn't matter how clever those chunks were written, because I got rid of them completely.

I think this is what the author speaks about.


They may just be trying to express the thought that simpler code is both easier to understand and often more efficient. Don't forget Joel Spolsky's contributions to the effort; he's the one who coined the term "architecture astronaut".



Definitely. Some of the most efficient C code I have seen is incomprehensible to anyone but a C expert and even then it takes several minutes to understand all of the nuances of what might only be a 4-line function.


I experienced exactly this when I cracked open the source to a GNU tool to see if I could figure it out.


Sometimes "efficient" and "easy to understand and be sure is correct" don't have to be mutually exclusive; see this example [1] of Java and Go.

Note that the code is autogenerated, so it should be equally efficient. The Go version also happens to be very simple and no different than most humans would write by hand (without trying very hard to optimize).

[1] https://gist.github.com/shurcooL/9f94bbd021b4693cf584


The code samples in your gist aren't doing the same thing. The Java version decodes the UTF-8 stored in the protobuf into Java's native UTF-16 Strings on first access, while Go strings are native UTF-8 and so only a nil check is necessary.

Or are you saying that languages should always use UTF-8 natively? I would agree with you on that, but disagree that this proves your point that "efficient" and "easy to understand and verify correctness" aren't mutually exclusive. pb.getSomeId().charAt(1000) runs in constant time in Java (albeit failing to give correct data if getSomeId() contains codepoints higher than \uFFFF), but pb.GetSomeId()[1000] will give you garbage data in Go if your field contains non-ASCII text. To get a valid codepoint in Go, you'd need to do string([]rune(pb.GetSomeId())[1000]), which runs in linear time and omits the check for valid UTF-8 bytes.


That's a good point, it seems the Java code is checking if the entire string is valid UTF-8 while the Go version isn't. I wonder why the behavior of generated protobufs is different between the two.


I'm not disputing that efficient code can be easier to understand in some instances, just that the assertion that efficient code is easier to understand. Logically, disputing that just requires a single instance of efficient code that is hard to understand. I think that's a trivial enough example to be self evident. In reality, I'm just wondering what they were trying to convey with that statement. I doubt they would have written it without reason, so I'm curious to the reason.


Fair point.

It's possible when they said "efficient", they did not mean "hardware efficient, runs fast, doesn't use a lot of resources" but "developer efficient, faster to write and easier to understand". But that entire phrase as is doesn't make sense, I agree with that.

It's also possible to be a simple mistake. Maybe they went overboard with marketing phrases and claimed something that isn't quite true.


We never said that. The closest I can think of is that simple code (short stack, no DI, layering, etc.) is simpler AND faster at the same time, and in my talk I give specific examples.


To me, that sounds like you are saying simple code is often efficient (or that efficient code can by simple), not that efficient code is simpler (which is how I interpret the original text).

To be very clear, I don't doubt the author (you?) had a good point to make, just that it was unclear what that was from the way it was presented, and to such a degree that it took me out of the flow of reading the post, and perhaps a less ambiguous way of expressing that concept (or omitting it, if it's expressed succinctly elsewhere) would be clearer and more effective.


Sorry, I'm not the author, I'm the guy at Stack Overflow that's being cited by the article (Marco C.).


All, true, which is why I outlined my assumptions and left it open for others to help try to figure out. :)

Unfortunately, if it is just poor communication on their part, we'll likely get no answers that can be considered more likely than others without original author or someone related (work-wise) piping up.


The generated Java code is just bad. You can simplify it by adding imports and removing the redundant variable: https://gist.github.com/electrum/d2f7668f2a7eb95420a9

Of course, as others have mentioned, it is validating the UTF-8 but the Go version is not.


It's not clear to me what argument the example is supporting.

The Go code is very concise and the Java code is very verbose.

The Go code does look more efficient but what is ImpressionData? Where is it checking the string is valid utf8?


Why would you send a string which is not valid utf8 over the wire in your system? That's the kind of validation that should probably be done prior to that. Or if it hasn't, you can do the validation manually on the receiver. There's no reason to incur the cost on each transmission.


    users=db.get("SELECT name FROM users WHERE group='admin'")
is more efficient and understandable then:

    users=[];
    tmp=db.get("SELECT name,group FROM users")
    for (i=0;i<tmp.count();i++)
    {
      if (tmp[i]['group']=='admin') users[]=tmp[i][name];
    }


But who in their right mind would do the second one?

Obviously you can make code both less efficient and less readable. But starting with code that a competent programmer has written, I find it seldom makes it more readable when you make it more efficient.


  But who in their right mind would do the second one?
Oh abritishguy, I can assure you that the world is awash in such magical code snippets.


> competent programmer


It's amazing the sorts of things otherwise sharp programmers will write when they're tired, hurried, and devoting cycles to more interesting/complicated parts of an implementation.


> true scotsman


>>But who in their right mind would do the second one?

Surely you jest. I don't know who, but their handiwork is everywhere.


People using ORM can end up writing the second one without it being obvious.


i tend to agree. take dijkstra's algorith implemented with a fibonacci heap or something very simple like

for i = 1 to 100 if x = this do that and something with i else something else with i

easy to read, less efficient than: if x = this for i = 1 to 100 do that and something with i else for i = 1 to 100 do something else with i

from my experience, compilers usually dont hoist very well

edit: sorry, spaces didnt come out well


This is where a good abstraction layer can pay dividends. Of course, a bad abstraction layer (as evidenced by Spolsky's "leaky abstraction" post (http://www.joelonsoftware.com/articles/LeakyAbstractions.htm...) on the opposite hand can add immeasurable cost.


Not to mention, you'd never write code like the second one in a .NET ecosystem, unless you were purposefully trying to write bad, unmaintainable code.




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

Search: