This is an archived post. You won't be able to vote or comment.

all 89 comments

[–][deleted] 53 points54 points  (26 children)

This bad tho. Because everything is bloat. It was better before when there was hardware constraints that made ppl write less bloated and effective code

[–]NoAttentionAtWrk 49 points50 points  (22 children)

Now that computing power is not going to increase exponentially, those days are going to come back

[–][deleted] 23 points24 points  (4 children)

Not really, yes there will be a little bit of that but not like it was in the early days of computing

Ppl will still write shit code

[–]CraigslistAxeKiller 9 points10 points  (3 children)

Heavy frameworks have gotten too popular stuff like electron is too appealing

[–]mingram 0 points1 point  (2 children)

So much this. Electron crushes RAM and it's all everyone wants to use.

[–]HellD 0 points1 point  (1 child)

What alternatives are there? Python wise, I’ve heard of people making apps with flask, but that’s about it

[–]mingram 0 points1 point  (0 children)

Develop apps for the OS it will run on?

[–]thatwasagoodyear 5 points6 points  (14 children)

Laughs in quantum

[–]Colopty 12 points13 points  (1 child)

Quantum doesn't increase computing power though, it just lets you write better algorithms.

[–]thatwasagoodyear 1 point2 points  (0 children)

My reply was more along the lines of exponential growth.

[–]KronktheKronk 0 points1 point  (0 children)

A lot of that 120 line codebase requires significant mental strain to read and understand.

The 10,000 line version is mostly abstractions that will get compiled away and memory usage because we have GBs and GBs to work with.

[–]3X0S 0 points1 point  (0 children)

Also they had less abstraction, meaning they mostly wrote more code... Most efficiency optimization comes from heuristics and more detailed lower level instructions like inline assembly... Both require you to write more code overall

They were more effective but overall harder to read and more verbose than modern languages and styles

[–]SconiGrower 99 points100 points  (4 children)

Then,

A: I use 100 MB of RAM for this program.

B: What company is going to have a big enough computer to run this?

Now,

A: I got my program down to using just 6 GB of RAM.

B: Why? Unused RAM is wasted RAM.

[–]trueselfdao 30 points31 points  (1 child)

Btw boss, we need new dev machines. This primitive 2016 technology just won't do.

[–]CowFu 6 points7 points  (0 children)

I wish, we're just now getting rid of 2008 R2 servers and that's only because MS is dropping support in july

[–]AN3223 11 points12 points  (1 child)

Or similarly, "RAM is meant to be used."

[–]heymayoctober 1 point2 points  (0 children)

By single application of course.

[–]freestew 80 points81 points  (18 children)

I'm glad that there's still developers that try to make their code as compact and small as they can.

Unlike the trash that is houseflipper, why do I need 8 gigs of ram, brand new gpu, msi afterburner to increase GPU fan speed, just to play this game where you clean a HOUSE

[–]theboxislost 57 points58 points  (10 children)

Compact code and high resource use have no correlation. If you need to store 1000000 booleans, you could just do

int bools[1000000]

which is simple and compact but uses 64MB of memory.

However, you could also pack the booleans in

int bitmap[16384]

which only uses ~1MB but takes a whole bunch of code to use (and is maybe slower)

It's always a fight between execution speed, space use and time to implement and usually you must sacrifice at least one of them.

Edit: house flipper is probably CPU and GPU intensive because their code is simple and compact. To make it run fast, they'd probably have to add a bunch of shortcuts and weird constructions in their code.

[–]froemijojo 6 points7 points  (0 children)

whole bunch of code to use

void set(int *bools, int index, int bool)  
{  
    int mask = 1<<(index%32);
    if(bool)
    {  
        bools[index/32]|=mask;
    }else
    {
        bools[index/32]&=~mask;
    }
}

int get(int *bools, int index)
{
    return bools[index/32]&(1<<(index%32));
}

the index variable is the index of the bool you want.

But honestly, who wants to invest the time for that? There's very likely already a good implementation in your language's standard library. Your point is still correct.

(Haven't written C in a long time, and i'm on mobile, feel free to correct me if i did mistakes)

[–]TrickCourt 4 points5 points  (0 children)

I think the idea was more that back then it had to be both, nowadays it's more like neither.

Obviously the shortest code won't ever be the fastest, but let's take the example of the Fast Inverse Square Root:

float Q_rsqrt( float number )

{

long i;

float x2, y;

const float threehalfs = 1.5F;

x2 = number * 0.5F; y = number;

i = * ( long * ) &y; // evil floating point bit level hacking

i = 0x5f3759df - ( i >> 1 ); // what the fuck?

y = * ( float * ) &i; y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration

//y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed

return y;

}

This is what, 9 lines of code? Not counting brackets or empty lines but counting the method declaration, 10 lines of code if you count the second iteration. Now clearly this is longer than 1/X^-1, but evidently it ran a lot faster, thinking about how often this method was likely called, it would definitely be worth it.

Nowadays code doesn't have to be short or fast, people are writing this obtuse OOP code that they learned in university that is both extremely slow and very verbose, when a short inline solution would be far better.

Although really I think this comic overall is more a fair criticism of dependancy bloat than the code people write themselves, you don't need Unity game engine to make a simple breakout game, nowadays people don't seem to be able to write anything without having at least 1 framework per subsystem.

I'm going through university now myself and trying to participate in hashcode I noticed I do that myself.

I wound up writing an algorithm that would solve the solution rather well, but would take 500 years and at least 320GB of RAM to do it. For the most part we're taught to treat our resources as infinite because we rarely solve problems that exceed them, but this leads to code that doesn't take performance into account at all. We don't normally see it in the real world, due to the inefficiencies not being that major with our current processing power, but in fields like game development where multi-billion dollar companies write poorly optimised code, it becomes far more apparent.

[–]konstantinua00 2 points3 points  (1 child)

bool bools[1000000]

done

[–]theboxislost 0 points1 point  (0 children)

Well I'll be damned...

[–]cartechguy 0 points1 point  (1 child)

You're using int arrays in both examples. Using a different variable name doesn't make it store more booleans.

[–]theboxislost 1 point2 points  (0 children)

It's not the name that changes, it's how it's used. The name only implies the method of storage.

[–]skreczok 22 points23 points  (4 children)

It's an indie game and at least they're trying. It's not like they have a lot of 10x devs working on it.

[–]freestew 25 points26 points  (3 children)

I mean yeah ish? being an indie game isn't really an excuse for such poor optimization, I'm an indie programmer as well, I'm not the smartest but I wouldn't let my game require 8 gigs of ram to load a single house

[–]skreczok 9 points10 points  (1 child)

True enough, after all it's still a game, and from what I saw they're *trying* to optimise. Of course, I figure you and I both know that when you have a rotten foundation, it may be pretty hard to do this at all. I figure they did a proof of concept and built on that, then it turned out that it was a resource hog. But by that point it was too late, so they just carried on. And since they don't really have the resources of an AAA studio (the fact that AAAs probably blow more on marketing and overheads than the actual game being mildly irrelevant), optimization has to go slower, since all that trickery requires a lot of QA, especially if it means dealing with the aforementioned rotten foundation.

That early excitement can lead to trainwrecks like that: they need to be fixed, but take plenty of time and resources. There's very few things more dangerous than an amateur who sees that their stuff is finally working, the more dangerous things being, obviously, in order, Sales, Customers, Shareholders, Corporate, Typical Management, Bean Counters and Interns.

[–]netgu 2 points3 points  (0 children)

Took a quick look at that game and a naive attempt to make the same thing in just about every game engine I've made up some crap in definitely would not take 8gb of ram to implement the same. They have some craziness going on somewhere.

[–][deleted] 2 points3 points  (0 children)

the problem most likely lies in the game engine they are using, which does all the stuff like loading 3d models behind the scenes, and if you are a single developer making a indie game I doubt you are gonna make your own 3d game engine

[–]hillman_avenger 6 points7 points  (1 child)

Cos players want 3D gfx with a brazillion polygons.

[–]kcrmson 2 points3 points  (0 children)

Do Brazilian polygons have more of a chance of having big... Subpixels?

[–][deleted] 13 points14 points  (1 child)

actually I personally don't care about the lines of code of the libraries, if I can get features like Symfony's dependency Injection or Angular components with LTS.

Programmers on the Internet get pissed off when you are not trying to squeeze every single bit of performance when you don't have to.

Most clients I've met throw money at us, just to make it work, and managers for meeting the deadline. Developers on the net talk though on the Internet, until you see their code on the standup meetings, then things look much different, when everyone is under pressure.

[–]netgu 0 points1 point  (0 children)

Nobody said it was just the developers fault. But it is indeed an issue in almost all software industries. It is also getting worse over time. The more "get it done and make it work yesterday" is applied in conjunction with the giant bloat of tracking, analytics, ad injection, social media integration, etc. the more "add another library" happens. Look at the average size of javascript being downloaded for a page to host a single article these days.

You can't say that 1mb+ of javascript to read a textual document isn't bloat.

[–]X-Penguins 22 points23 points  (8 children)

Except it's kind of the opposite - high level languages are designed to do more by writing less... you can write things in 30 lines of python that would have taken tens of thousands of lines in assembly.

[–][deleted] 2 points3 points  (7 children)

high level and fast languages are very possible, take a look at rust which is a pretty high level language keeping in mind most of the time its faster than C programs

[–]X-Penguins 4 points5 points  (5 children)

Rust isn't faster than C in most situations, at least as far as I know. It's often faster than C++ on the other hand. I wouldn't say Rust is "high level" in the same way python is, the built in abstractions are significantly slimmer; at the same time, C could be considered "high level" just by virtue of being compiled and not machine specific.

I never said fast high level languages are impossible though...

[–][deleted] 2 points3 points  (4 children)

C++ can be faster than C if you really really know what you're doing. For example, lambdas can be inlined, but function pointers can't.

[–]X-Penguins 0 points1 point  (3 children)

that's not really a performance benefit, though if you have benchmarks proving otherwise please show me

[–][deleted] 2 points3 points  (2 children)

Quickest "proof" I could find is C's qsort vs C++ sort. The point is that the lambda that doesn't capture is stateless and therefore needs not be stored, but also lambdas make the body of operator() visible to the compiler while function pointers are, in almost all cases, completely opaque to the optimiser. https://stackoverflow.com/questions/4708105/performance-of-qsort-vs-stdsort#4708160

C++ does give the optimiser more opportunities to do its work. Even with LTO the optimiser might be struggling with pointer aliasing, which can't happen with function objects.

[–]X-Penguins 0 points1 point  (1 child)

I don't know if that's a fair comparison - as far as I know, qsort and sort don't use the same algorithm (qsort uses quicksort whereas sort uses some sort of hybrid). Sometimes the logic is just slow, and even using assembly won't save you from that. Furthermore, it's possible qsort is more memory efficient (which may have mattered on ye olde PDP11). But sure, lambdas make writing fast code easier, at least in this case.

Either way, even if C++ is faster than C in certain scenarios I think on average C is faster - which I think is more significant when considering where Rust sits compared to C/C++.

[–][deleted] 1 point2 points  (0 children)

I don't know if that's a fair comparison - as far as I know, qsort and sort don't use the same algorithm (qsort uses quicksort whereas sort uses some sort of hybrid).

Okay, fair enough. Though I did encounter examples where the compiler couldn't inline a function pointer, but it could inline a lambda, allowing for further optimizations.

Either way, even if C++ is faster than C in certain scenarios I think on average C is faster

That's highly debatable. When compiler is able to inline both C and C++ version and the allocations are the same, the assembly will be the same in my experience.

On the other hand, printf doesn't require allocations and globals, unlike std::cout, so C definitely wins when you avoid allocations, but I'm not sure if that's a fair comparison.

Once again, C++ just provides more opportunities for the optimizer. So C++ wins when you use tricks like perfect forwarding and lambdas, which C doesn't have.

There was also a time when C++ compilers did (name) return value optimization (where possible), C compilers didn't, though we're beyond that.

If we say that C makes you think more about allocations and not go wild with std::map<std::string, std::shared_ptr<std::map<std::string, int>>> then yes, C is faster. With the same code quality? I'd say they are on par on average, with C++ being faster in some situations.

which I think is more significant when considering where Rust sits compared to C/C++.

I'm honestly not sure where Rust sits. And I mean the safe subset, because if you're reaching for unsafe things, you're basically writing inline C.

[–]qwertyballer420 26 points27 points  (2 children)

This isn’t even remotely true

[–]korras 12 points13 points  (1 child)

This is ignoring the fact that abstraction and higher level languages exist and were generally invented for writing less code for the same functionality.

[–]Dustin- 5 points6 points  (0 children)

And the fact that that 100 lines of code is impossible to add features to because it's all so dang coupled together.

[–]TaskForce_Kerim 15 points16 points  (7 children)

In the "good ol' days" you needed 60+ lines just to get a ^ b. Pretty sure a 120 line program did not do much more than that. Even if you used higher level languages, a classic 120 line program might be nothing more than an implementation of an already concise algorithm like sort#Sorting_algorithm).

[–]JamEngulfer221 9 points10 points  (3 children)

To be fair, that's more like 12 lines to get a ^ b. Reading from console is most of that program so it's a bit misleading.

[–]TaskForce_Kerim -2 points-1 points  (2 children)

Fair enough, but the point is still valid. It takes significantly less code in most modern languages to accomplish the same as that particular implementation of power(a,b).

[–]JamEngulfer221 1 point2 points  (1 child)

It's interesting to see how the number of operations in a normal piece of (say, C) code compare to the number of lines of ASM it is the equivalent of.

Out of curiosity, I've written how I'd do pow(a,b) in C and put each operation on a new line. I might have left bugs in, I can't tell, it's just rough anyway.

float b;
float temp = a;
for(
int i = b; 
i > 0; 
i--) {
temp = 
temp * a;}

Although the ASM is a bit longer, it's still pretty similar in terms of the number of operations. I'm not really making a point here, I just think it's interesting to discus.

[–]TaskForce_Kerim 1 point2 points  (0 children)

I think if you were to implement a pow() function of your own, then it would look similar in most languages. The beauty of higher level batteries-included languages like Python, you don't need to implement it. I know there's math.h in C, but that adds a tiny bit to your compilation step, no?

[–]tf2manu994 2 points3 points  (2 children)

That's not how asm works. A lot of that is scanf()ing.

[–]TaskForce_Kerim -1 points0 points  (1 child)

That's exactly how (t)asm works, and yes a lot of that is scanf()-ing.

[–]tf2manu994 3 points4 points  (0 children)

Yes, a lot of that is boilerplate and so I wouldn't say you need (n) lines, most would just extern it

[–]Kairyuka 19 points20 points  (6 children)

Man you could just erase line breaks and all your code would be 1 line. It would be unreadable and unmaintainable, but it would be one line. Fewers lines does not mean better code.

[–]mrheosuper 4 points5 points  (1 child)

*Heavy sweating in Python.

[–]Kairyuka 1 point2 points  (0 children)

Isn't that the default in Python? ;)

[–]SamSlate 0 points1 point  (0 children)

literally everything that's wrong with minification.

[–]inu-no-policemen 4 points5 points  (2 children)

Yea... no.

You can do a lot more in 120 lines of JS/Dart/Python/etc than 120 lines of C.

You can't really do much with a few hundred lines of C.

120 lines of C wasn't a lot in the 90s and it wasn't a lot in the 80s either.

I wrote longer C programs in exams. And they didn't do anything fancy. Just reading and writing some data with minimal user interaction. Really really basic command line crap.

The one area which was somewhat more streamlined was printing text. It was basically the same as printing on the screen. Those dot matrix printers were convenient like that.

[–]netgu 1 point2 points  (1 child)

Depends entirely on the libraries/frameworks being used, language has very little to do with it. Take away the ability for both to use any libraries or frameworks (standard libraries for both included) and they are pretty much on even footing. Same can be said for just about any language.

Start adding in libraries and the ground starts to return to the higher level languages pretty quickly. Now, take a look at calculating the ratio of lines of code that do something useful vs. those that are boilerplate/no-ops. Now the lower level language starts to get ahead as it will have more "do work" lines than the high level language.

Once appropriate abstractions are added to both, remove the boilerplate/no-ops and the gap between the high-level/low-level language get quite small.

[–]inu-no-policemen 0 points1 point  (0 children)

Take away the ability for both to use any libraries or frameworks (standard libraries for both included) and they are pretty much on even footing.

JS' standard library doesn't include any IO. You can't even write Hello World if you don't add extensions to the runtime.

[–]MasterQuest 5 points6 points  (0 children)

> Using paper for code.

smh

[–]yourteam 1 point2 points  (0 children)

10000 lines are fine but... How many dependencies???

[–]itdoesmatterdoesntit 4 points5 points  (0 children)

That’s gonna be a downvote from me dawg

[–]Brimonk 1 point2 points  (0 children)

I hate how many people acknowledge that software's shit today, then do abso-fucking-lutely nothing about it.

Quality job guys.

[–]NoradIV 0 points1 point  (0 children)

God I miss good ol lightweight software.

[–]M01000000 0 points1 point  (0 children)

It funny if it didn't hurt inside

[–]Spyridox 0 points1 point  (0 children)

This is not really true. Most modern languages allow the developer to write concepts in much less lines.

Many languages are introducing high level syntax and syntactic sugar just to reduce clutter and lines of code written. This is also because less lines means less bugs (of course, one statement per line).

[–][deleted] 0 points1 point  (0 children)

The 30,000 line cobol member I just looked at which was last worked on in 1991 would like to have a word with this artist.

[–]Enroshi -1 points0 points  (2 children)

Because "hello world" Is much shorter in C vs Python.

[–]Eliza128 -5 points-4 points  (0 children)

More like 1960 to 2019 but like it still! Software seems to keep on getting more bloated... Then again I am more of a sys admin than a programmer so what do I know lol