Hacker News new | ask | show | jobs
by aappleby 673 days ago
Good refactoring should significantly reduce the size or complexity of a codebase.

These two metrics are interrelated, but as a general rule if the gzipped size of the codebase (ignoring comments) does not go down, it's probably not a good refactoring.

1 comments

I'm going to disagree and see what other people say.

I don't think that reduction of size is of any relevance. I admit my own refractors tend to make things smaller but it's only a tendency. Most definitely some increase the size overall. I'm currently refactoring a code base – for each item there used to be one class. Each object was examined after creation then a runtime flag was set: Rejected or Accepted. As the code crew I found I was wasting a lot of time around this Accepted/Rejected stuff. Now I'm refactoring so I have two classes for each item, one for when it's Accepted and one for when it's Rejected. The amount of boilerplate has definitely bulked up the code but it will be worth it.

As for complexity, I don't know.

The only thing I refactor for is human comprehensibility. That is the final goal. What other goal can there be?

> I don't think that reduction of size is of any relevance.

More code equals more bugs. This has been a pretty consistent finding dating back decades. Simpler and smaller code bases will generally have fewer bugs.

https://news.ycombinator.com/item?id=33566329

Sure, comprehensibility is the terminal goal—but size reduction is relevant because it’s an easily measured, decently predictive proxy for that. No, code-golfing 3 lines down to one doesn’t help, but the bigger size differences are always of the “composition over XYZ” variety that change the entire complexity class of how much code you need to write (like React letting people write O(states) rendering code instead of O(transitions)).
Size reduction usually follows but not necessarily. That is easily measured is an irrelevance. The claim that its a decently predictive proxy I can't buy at the moment, can you try justifying that? Some very terse code can be very hard to understand without (comprehensive) commenting eg. https://en.wikipedia.org/wiki/Fast_inverse_square_root#Overv...

Maybe you're right. I've had a drink, I'll think over it in the morning, thanks.

If you don't care about performance, we can make that code a lot shorter.

  float Q_rsqrt(float number) {
    return 1 / sqrt(number);
  }
The "fast inverse square root" is absolutely 100% all about performance. For it to make sense to use as a counter-example, you need to show alternate code that still meets the contract (the contract being: be as fast as this code), that is longer, and clearer.
I was saying that shorter code is not necessarily more readable. But what you're talking about is optimisation and I'm fine with that, uglier code for higher speed (or whatever). But is that refactoring? I don't think so. I may have led you a bit down the garden path here.
Other goals can be performance, testability
Testability is a good one, thanks. I'm not so sure about performance and I'll chew that one over for now.
Imagine that you've refactored code and reduced complexity, but also reduced performance (the caching example) - would you move forward with the refactor?

From my perspective there should always be a buy in - after refactoring the system is more understandable, but also more coupled. Is this fine? If no, can given refactor be merged now and result tackled in separate refactor. Caching refactor can have a buy in as well - ie. remove caching because given request shouldn't be cached, or this functionality should be decoupled and done elsewhere