Hey guys, I would like some pointer (no, not that kind) on removing bloat in code. Here is a fully functional piece of code that I wrote which I'm worried about bloat in. How do I shorten this?
int get_input()
{
int count, paren_count, total_count, c;
char *input, *temp;
>>14
If we are going to allow modifications we could add a lot more to it #define GC getchar
#define C char
#define M malloc
#define SO sizeof
#define RA realloc
#define I int
#define B break
#define F free
#define P printf
#define R return
#define Q if
#define EF else if
#define FR for
and then have I g(){I u,p,t,c;C *i,*m;i=(C*)M(500*SO(C));Q(i==0)R 0;P("%% ");FR(u=p=t=0;(c=GC())!=-1;u++,i++,t++){Q(u==499){i-=t;m=(C*)RA(i,(500+t)*SO(C));Q(m==0)R 0;i=m;i+=t;}Q(c=='\n'){*i='\0';m=i;m-=(u);u=0;FR(;*m!='\0';m++){Q(*m=='(')p++;EF(*m==')')p--;}Q(p==0)B;P(" ");}*i=c;}*m='\0';i-=t;P("%s\n",i);F(i);R 0;}
Thne we should replace everything that is >1 letter long with a single character.
>>16
If we allow a header file we could even OMPTIMIZE even further:
h.h #define GC getchar
#define C char
#define M malloc
#define SO sizeof
#define RA realloc
#define I int
#define B break
#define F free
#define P printf
#define R return
#define Q if
#define EF else if
#define FR for
#define G I g(){I u,p,t,c;C *i,*m;i=(C*)M(500*SO(C));Q(i==0)R 0;P("%% ");FR(u=p=t=0;(c=GC())!=-1;u++,i++,t++){Q(u==499){i-=t;m=(C*)RA(i,(500+t)*SO(C));Q(m==0)R 0;i=m;i+=t;}Q(c=='\n'){*i='\0';m=i;m-=(u);u=0;FR(;*m!='\0';m++){Q(*m=='(')p++;EF(*m==')')p--;}Q(p==0)B;P(" ");}*i=c;}*m='\0';i-=t;P("%s\n",i);F(i);R 0;}
>>8
I'm not, and I already have. The plan was to get this to work first and then clean it up. >>5
Input = realloc (input,...)
Realloc isn't gauranteed to work fool.
- pulls out increment as a constant
- returns -1 on failure (you were returning 0 everywhere for some reason)
- checks for end of file (ctrl+d or closed pipe)
- checks for too many closing parens
- adds CODE COMMENTS, so you can actually see what's going on
Name:
Anonymous2010-02-24 12:44
>>27
- also, doesn't fuck around with your input pointer, so you can use it with garbage collectors and other analysis tools. It's a little scary that OP doesn't keep a fixed pointer to the start of the buffer.
>>22
You think I give a shit if realloc works or not? You think his program is going to be able to gracefully degrade if it runs out of memory? Get the fuck out with your useless pedantry.
Name:
Anonymous2010-02-24 18:24
>>35
My program? Frankly, I like protection.
Anyway today I fixed the bloat issue. I'll post it later for show.
Name:
Anonymous2010-02-24 18:42
>>36 Those who give up efficiency for security deserve neither.
Name:
Anonymous2010-02-24 19:04
>>37
Okay here's the thing: I am writing an interpreted programming language, this function is part of the shell.
God damn, I need to free all of the memory in the linked list before it exits, or else bad things will happen, and you know it.
>>38
Why don't you just write it in a higher level language? Until you have it working, worrying about efficiency is a waste.
Name:
Anonymous2010-02-24 19:50
>>39
I hate higher level languages in general (save for languages like scheme and perl), plus the linked lists are so much easier in C. And you're right, worrying about efficiency in the beginning is stupid, I was just saying how safety is necessary for what I'm doing.
Any way, here's my fixed version. Sorry if I don't get the bbcode right
int get_input()
{
int count, post_count;
char *input = NULL, *temp, c;
It's funny how people want efficiency, so they use C, sometimes they want to embed a language, but then they realize making a full compiler would be too much work for them, so they end up making an interpreter, which would mean overall slower code execution (the only time when interpreters beat compilers is when the expressions are short and easy to interpret, as well as situations when your interpreted code calls EVAL internally for everything it does - which is not a good programming practice (lol FEXPRS)). Instead they could choose something more high-level, but on average slightly slower than C (unless more work is done to optimize things), which allows code transformation, and gives you direct runtime access to a compiler. Such a language could be Common Lisp, but it's not the only one(however it's one of the few languages which support real macros).
Which would in the end give you faster execution than what interpreted code could give you, and if you really wanted fast EVAL for some reason? Just switch to a CL implementation with a fast compiler or interpreter - little to no code modification required.
>>43
Why not? Making compilers isn't THAT hard, but if you could reuse a good compiler backend, that saves you a lot of time, especially if you can switch backends at any time (such as with CL).
Name:
Anonymous2010-02-24 20:39
>>41 but then they realize making a full compiler would be too much work for them, so they end up making an interpreter,
It's not (just) that making a compiler is a lot of work, it's that traditional ways of making a compiler mean a lot of upfront work before you get any results. Abdulaziz Ghuluom has a paper on incremental compiler construction which is interesting and should give the same instant gratification you get from writing interpreters. the only time when interpreters beat compilers is when the expressions are short and easy to interpret, as well as situations when your interpreted code calls EVAL internally for everything it does
That depends on whether or not we count JITs as interpreters. Most people wouldn't, I guess, but I see no reason to assume that we can't make fast interpreters. As an aside, if you are going to be calling eval on every expression, why don't you just implement your language as a series of reader macros (assuming that this was Lisp)?
Name:
Anonymous2010-02-24 20:40
>>44 Also, I really don't see how anything in this thread is related to 'bloat'.
When do we ever stay on topic
>>46
If you're making a completly new language, there's no real reason to bother with reader macros(unless you want to add support for the language in the standard reader). Just make a new reader which lexes and parses the language, and gives you an AST(in form of S-EXPRs, or something else), and then you transform that AST into lisp code using some macro system of your own making (or just plain simple macros - this doesn't matter much, as reimplementing the macro system can be done with very little effort(it's just simple code transforms registered in a global environment)), after the code transforms have been performed, you just end up with a set of special forms which can be compiled, or you could transform the code to plain old lisp forms, which can then be passed to COMPILE. Basically, you're making a front-end for a compiler which converts your language to lisp, which can then be compiled directly at runtime.
Name:
Anonymous2010-02-24 21:25
>>45
Because I want to make it cross platform, for one thing. I'm considering putting a compiler in there for people who want to make a standalone, so it's not entirely ruled out as a possibility.
>>49
There's CL compilers which compile to C and some interpreters written in C, those should not be limited to CPU arch (that said, how many platforms do you intend to support? Most major ones have CL compilers working on them, but I guess not all of them. Maybe Scheme would be a simpler choice for this, however ECL should fit the bill too.)
>>55
>implying one of the reasons I don't hate Java is because of its speed.
Name:
Anonymous2010-02-24 23:41
>>55
No, but the JVM is shit to begin with, due to shortsighted issues like the lack of tail recursion and the atrocious startup time. A more professional way to do it is with a runtime that allows you to deploy compiled binaries, such as SBCL's.
>>62
char is not fixed by the c standard. Lrn2 CHAR_BIT
Name:
!/c/0NTHWZ62010-02-25 8:24
.
Name:
Anonymous2010-02-25 9:53
>>62,63
C99 6.5.3.4 p.3
"When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1."
>>63
CHAR_BIT gives the number of bits in a byte on the current platform. char is always exactly one byte (even in C89), however many bits that may be.
Common Lisp is a really bad choice if you're looking for ways to reduce bloat. It will eat up 30-60MB RAM depending on the implementation. And that's just the Lisp environment itself without any of your own code.
Unless you're using something like CLISP (~8MB), but it's slow.
>>70
It's your whole environment, the compiler and what not.
Name:
Anonymous2010-02-26 15:08
>>71,72
But we didn't have 30 (or even 8) megabytes handy back in the... sixties. I refuse to believe that bloat predates capacity. That would be a world too cruel for life.
>>70 >>73
That's the price you pay when you're trying to emulate an incompatible LISP computer instead of acting like a proper program on the actual operating system. No sharing any memory either if you fire up multiple programs. It's sad.
>>75
So what you're trying to say is faggotLISP is dead! Long live Lisp!faggot -- ?
Name:
Anonymous2010-02-26 16:57
>>76
Don't believe in The Sussman, believe in The Sussman who believes in you.
Name:
Anonymous2010-02-26 17:00
>>76
I'm just trying to say that current Common Lisp implementations are doing it wrong. Lisp machines are dead. They should stop trying to act like one.
Name:
Anonymous2010-02-26 18:39
>>68,78
If you want small memory footprint and memory sharing (copy-on-write), just use ECL. The runtime is in a shared library, and actual applications are tiny.
I actually like those "huge" image-based lisps as they're 100% dynamic in what you can change at runtime (want to recompile a piece of SBCL's kernel, sure, it's just one hotkey away! Hotpatching as never been easier), and the memory footprint being some 30mb doesn't bother me since I don't use a computer from 20 years ago.
Name:
Anonymous2010-02-26 21:31
>79
Even with ECL the runtime overhead is around 26MB.
Per program, I just checked. Unless, of course, you run it as a "Lisp server" with each program running in a different thread. At least that's how it's supposed to be done from what I've read.
>>80
Either way works just fine really, but beware that if a thread patches some system routines or global values, this could interfere with the other threads and mess things up. I guess those are the dangers of shared program memory. It's not nearly as bad as with the old DOS/Win3.11 shared-memory aproaches since Lisp is much more high-level, but it's still possible for an application to easily crash the whole world if it wants to.
Name:
Anonymous2010-02-26 21:52
>>78
So, it's more of a [i]fag[...] Sussman is dead. - LISPgot[i] type situation then. (Try not to mind my active ``faggot-quotes'' research.)
>>79
I can appreciate the utility of a 30MB overhead, but I like to write for small devices. I know almost everything has at least 128MB these days, but my preferred target platform only has 4.
It's okay though. There are lispy enough things that aren't so um bad.
>>82
Well, CL was never intended to be that tiny, maybe some 8MB for a full CL, but I have my doubts. R5RS' could be smaller I guess, or maybe some Lisp500 variant.