Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

Elegant code & Efficient code

Name: Anonymous 2007-01-28 12:40

Elegant code & Efficient code, are they inversly proportional?

Name: Anonymous 2007-01-28 13:01

Inside this body, we have added powerful and eregant system.

Name: Anonymous 2007-01-28 16:21

No, it's complexity, elegance, and efficiency that you include. You can choose two: complex/elegant, efficient/elegant, complex/efficient.

Name: Anonymous 2007-01-28 17:07

>>1
Not always. Here is a paper about a Haskell library that provides elegance and speed for string oriented processing:

http://www.cse.unsw.edu.au/~dons/papers/fusion.pdf

The library is written to work with the compiler to provide aggressive, on-the-fly optimization. You can write idiomatic, high level 'elegant' code using higher-order functions like map and fold, but it gets compiled to very efficient, simple loops.

Using this library, I have seen my 'elegant' code have over a 50x increase in runtime when optimization was enabled.

This type of optimization with out sacrificing elegance is possible because the bytestring library itself contains a bunch of domain specific optimization rules that the compiler can use.

This is, of course, possible in other languages. For example, lisp macros are often used to allow the programmer to write elegant code that is automatically rewritten at compile-time into more efficient code.

At the other end of the spectrum, there are assembly language super-optimizers.
 http://delivery.acm.org/10.1145/520000/512566/p304-joshi.pdf?key1=512566&key2=1171200711&coll=&dl=acm&CFID=15151515&CFTOKEN=6184618

Superoptimizers attempt to take a block of assembly code and create a new block of assembly code that functionally is equivalent, but faster. In some cases, it can even be mathematically proven that the new code is the fastest possible way to implement the code. Unfortunately, this problem is NP-complete -- so it can take a lot of time to come up with the optimal solution. Also, because the optimizer is lacking context, it is limited in what optimizations it can do. It must provide code that leaves the final state of the machine in the exact same state as the original code.

Of course, sometimes the biggest optimizations come from using a better algorithm in the first place.

Name: Anonymous 2007-01-28 19:16

elegant and efficient code:
sub factor{
 my @f,$n=pop;
 map{$n/=$_,push @f,$_ until $n%$_}2..$n/2;
 @f}

Name: Anonymous 2007-01-28 19:41

>>5
"Elegant"?

Name: Anonymous 2007-01-28 20:24 (sage)

>>6
i'd like to see you write a more elegant function that does what that one does.

Name: Anonymous 2007-01-28 20:49

>>5

I did this in 5 minutes.

########################
sub factor(){
 my ($inputNumber) = @_;
 my @outputFactors = ();
 my @potentialFactors = (2..$inputNumber);

 foreach my $currentPotentialFactor ( @potentialFactors ){
     unless( $inputNumber % $currentPotentialFactor ){
     push(@outputFactors, $currentPotentialFactor);
     }
 }

 return \@outputFactors;
}
###########################

Mine works, yours doesn't, by the way.  Good luck trying to debug that awful POS code you wrote - which is pretty much the antithesis of elegant.  If it worked, it might be classified as interesting, but not elegant.  Plus you are raping the map builtin.  Map returns a list, which you aren't using, and is (and should always be) used as a way to transform one list into another, taking a coderef as the transformation algorithm.  You are bastardizing it into a strange looping construct because its "neat".  For, and Foreach, are both far better suited to this task - and document this to the reader of your code much better.

Always write your code with the belief that the next person to have your job will be a raging psychopath with a gun, who knows where you life.  Pray I never work with you in the professional world.

Name: Anonymous 2007-01-28 22:26

>>8
fail for not working at all - "Too many arguments for main::factor..."

after changing "sub factor(){" to "sub factor{":
fail for returning an array ref instead of a list.

after changing "return \@outputFactors;" to "return @outputFactors;":
fail for including the given number in the returned list.

also, you are raping the push builtin. push returns the number of elements in the array after the push, which you aren't using. guess what, you don't have to use the return value just because it's there. "map" is just like "for", except that it returns a list *and looks nicer*. if i wanted a bunch of extra parentheses in my code i'd use lisp.

Name: Anonymous 2007-01-28 22:36

oh wait, the code in >>8 is even more broken than i thought...

the code in >>5 returns (2,2,5) for 20.
2 and 5 are both prime.
2*2*5==20

the code in >>8 returns (2,4,5,10,20) for 20.
4, 10, and 20 are not prime.
2*4*5*10*20!=20
MASSIVE FAIL.

Name: Anonymous 2007-01-28 23:11

>>10

Silly me, with a name like factor, I figured it would return the factors of a number or something.  Of course, since your code looked like the executable line noise Perl is so maligned for - it was far too difficult to discern that.

I did forget to add the ($) to the function declaration for the single argument, but if you call functions with ampersands or through the class/package, you dont have that issue.  Since I call all of my functions through the package/instance, I never have issues.

Returning a reference is for efficiency.  You clearly haven't done much work in C if you like to return things by value.  Of course, you could always use the wantarray builtin to determine which context you are being called in, and return appropriately.  But I never bother with the extra boolean compare.  There is rarely ever a reason to return a literal list/hash instead of a ref.

And, if you know anything about Perl arrays, you will know that push is, in fact, for pushing things onto the end of arrays.  The return int is simply there for convenience.  $array[$#array + 1] just isn't the same.  Its harder to read, and - in fact, its much slower.

Name: Anonymous 2007-01-29 4:23

UM LOL @ PERL FAGS WHO CANT EVEN WRITE THE MOST FUCKING SIMPLE PIECE OF CODE EVER.

(defun primep (n)
  (cond ((= 1 n) 'nil)
    ((= 2 n) t)
    ((evenp n) 'nil)
    (t (let ((limit (floor (sqrt n))))
         (do ((i 3 (incf i 2)))
         ((> i limit) t)
           (if (= 0 (mod n i)) (return-from primep 'nil)))))))

(defun find-largest-prime-divisor (n)
  (if (= n 2) 2
      (do ((i (1+ (floor (sqrt n))) (decf i)))
      ((and (= 0 (mod n i)) (primep i)) i))))

(defun prime-factorize (n)
  (let ((list '()) (factor 1))
    (do ((x n (/ x factor)))
    ((= 1 x))
      (setq factor
        (if (primep x) x
        (find-largest-prime-divisor x))
        list (cons factor list)))
    list))

Name: Anonymous 2007-01-29 4:23

>>12
also, not saying this is elegant code.. but GEEZ LERN TO WRITE THE MOST SIMPLE PROGRAM IN THE WORLDS.

Name: Anonymous 2007-01-29 7:41

>>1
its IMPOSSIBLE to write elegant and inefficient code.

Name: Anonymous 2007-01-29 9:44

Silly me, with a name like factor, I figured it would return the factors of a number or something.
why would i possibly want to do that? that would be completely useless.

Returning a reference is for efficiency.  You clearly haven't done much work in C if you like to return things by value.  Of course, you could always use the wantarray builtin to determine which context you are being called in, and return appropriately.  But I never bother with the extra boolean compare.  There is rarely ever a reason to return a literal list/hash instead of a ref.
perl is not c. returning a ref is not more efficient than returning a list. the only reason to return a ref is if you're returning multiple arrays and don't want them collapsed into one list.

Name: Anonymous 2007-01-29 12:06

>>12
Simple, but horrible :(

Name: Anonymous 2007-01-29 20:10

In before python or ruby fags.

Name: Anonymous 2007-01-29 20:52

>>15

Yeah ... factors are never important ... silly math ...

And Perl is C.  Well, C++ anyway.  Whether you realize it or not, Perl arrays are analogs for C++ STL vectors.  Most of the Perl builtins are C++ wrappers.  Try running this if you dont believe me about references being more efficient.  Its a simple benchmarking script that creates arrays, and does summations on a subset of those values - a simple operation that is done quite often in real world code.

#####################
use Benchmark qw(:all);
use constant LENGTH_OF_ARRAYS => 2000000;
use constant NUMBER_OF_ITERATIONS => 20000;

timethese( 100,
       {
           'With References' => \&UsesArrayReference,
           'With Literals' => \&UsesArrayLiteral
       }
       );

cmpthese( -5,
      {
          'With References' => \&UsesArrayReference,
          'With Literals' => \&UsesArrayLiteral
          }
      );

sub UsesArrayReference {
    my $iterations = NUMBER_OF_ITERATIONS();
    my $array = ReturnsArrayReference(LENGTH_OF_ARRAYS());
   
    my $total = 0;
    for( my $i = 0; $i < $iterations; $i++ ){
    $total += $array->[$i];
    }
    return $total;
}

sub UsesArrayLiteral {
    my $iterations = NUMBER_OF_ITERATIONS();
    my @array = ReturnsArrayLiteral(LENGTH_OF_ARRAYS());
   
    my $total = 0;
    for( my $i = 0; $i < $iterations; $i++ ){
    $total += $array[$i];
    }
    return $total;
}

sub ReturnsArrayReference {
    my ($lengthOfArray) = @_;
    my @array = (1..$lengthOfArray);
    return \@array;
}

sub ReturnsArrayLiteral {
    my ($lengthOfArray) = @_;
    my @array = (1..$lengthOfArray);
    return @array;
}
###################

Returning Perl Array literals, just like returning vector value types in C++, causes a copy of all the memory values into a new object.  Thats why we get these kind of results.

###########
Benchmark: timing 100 iterations of With Literals, With References...
With Literals: 88 wallclock secs (87.83 usr +  0.05 sys = 87.87 CPU) @  1.14/s (n=100)
With References: 44 wallclock secs (43.67 usr +  0.14 sys = 43.81 CPU) @  2.28/s (n=100)
                  Rate   With Literals With References
With Literals   1.14/s              --            -50%
With References 2.30/s            101%              --
###########

Hm ... what have we here ...

Of course, with huge sets of iterations, the copy becomes less significant.  So you can probably come up with some permutation of this script which shows them as closer in terms of efficiency, but the references will still be faster.

Name: Anonymous 2007-01-30 0:05

Perl shit uses 8 to 10X more memory per variable. It gets slow fast.

Name: Anonymous 2007-01-30 1:35

>>19
not if you have 4GB of DDR3 and 4MB L2 cache...

Name: Anonymous 2007-01-30 20:29

>>19

Perl can be efficient ... but its easy to screw up.  Lazy garbage collection, and its reference counter can get fooled with circular references pretty easily.  Plus its normal lax way of letting you poof package variables into existence (which dont go away easily) tends to make novice Perl programs bloat up pretty good.

That being said, if you are looking for efficiency - yeah, Perl isn't for you.  Neither is Java or .Net or any of the other high level languages for that matter.  Different tools for different jobs.  Perl is best used for code that works with unreliable sources, or code that has vague specs and needs to be uber-flexable.  Perl itself is very condusive to flexability, with its innate ability to do the Right Thing, and forgiving syntax.

Name: Anonymous 2007-01-31 15:25

>forgiving syntax
What a great euphemism for utterly shitty.

Name: Anonymous 2007-02-01 21:10

>>22

Perl is a language that doesn't force you into any one way of doing things.  Thats why you can use it for anything from simple shell scripting (where forgiving syntax is good) to huge professional-quality systems.  By default, Perl is very forgiving of mistakes - which makes it a wonderful language to learn in.  Then, when you are ready, you just put one little line in your driver :

use strict;

... and Perl will tell you everything it was being being quiet about before.  Most Perl programs should have this pragma enabled, but that doesn't mean that all have to.  Perl's philosophy is that the programmer knows whats best - and there is more than one way to do it.  To create a language that is restrictive to a certain way of thinking, or a certain way of writing code, is creating a language that is only applicable to a reduced problem set, and to a certain way of thinking.

Of course, with all the crappy programmers out there, it also means you get a load of stuff that runs, but looks like executable terminal gibberish.  That, however, is the programmer's fault - not the tool.

Name: Anonymous 2007-02-02 5:02

There's no excuse for allowing you to come up with shit that ranks worse than Spectrum BASIC. Problem is, you aren't the only person in the world who writes code. You need to use others' libraries (for which hopefully but not always you will not need to fix or change anything), and you need to work with others in projects. Even if you're properly disciplined and write proper code, the next guy's code will suck, and you'll have to deal with that suckage. This makes Perl a hell to maintain, a write-once language mostly.

Perl is very forgiving of mistakes - which makes it a wonderful language to learn in.
Not pointing out your mistakes when learning is not wonderful.

Perl's philosophy is that the programmer knows whats best
My philosophy is that I know what's best (though I may be wrong sometimes), and others don't always know what's best, and sometimes, what's best for me is not what's best for others, so less "23479034 ways to do things" will be helpful. Not only you may utterly dislike ways 673 and 1498, but you only know ways 1-100, while the next guy knows ways 101-200, and you can't read each other's code.

To create a language that is restrictive to a certain way of thinking, or a certain way of writing code, is creating a language that is only applicable to a reduced problem set, and to a certain way of thinking.
Almost all programming languages, and probably all, are limited to a reduced problem set, and suck outside it. This set may be larger or smaller, but it almost always, and probably always exists. It's good that a language requires certain uniformity because it becomes better for large projects and code reuse. You can't work with the next guy if you totally hate his style, or write /("%/()=#$/"#(/=()"/#%& hacks he won't understand. I consider restricting to a ceertain way of thinking good. If you don't like the style, you're out of luck, but you'll find a language that suits you. Those who do, find more uniformity. That said, I didn't find it so hard to adapt to Python, which at first had a few things I frowned upon (immutable strings, throwing OMG FUCK FUCK FUCK NO U exceptions for things I was used to do in Perl and PHP) and was not used to others because they simply did not exist in other languages I knew, but I found I could still do things the way I like and in two weeks I could read everyone's code and work something useful out of it.

Name: Anonymous 2007-02-02 20:59

>>24

I would have learned quite a bit faster had my C compiler not spewed ungodly numbers of errors as I tried to figure out how to get casting to work.  Perl's typeless system would have allowed me to gloss over the type drivel and focus on design - which I can apply to any languague.  Then, once I had design down, I could go and learn the nitty-gritty bits of whatever language I am using, in order to make it efficient.

Both have their place.

I suggest checking out CPAN if you think Perl is a write-once language.   There are many mature modules out there, and quite actively maintained.  Unit tested, tinderboxed, etc.

Any language can be write once.  I have seen (and currently maintain) 5000 line C# functions, because the person who wrote the C# was a tard.  It would have been the same in Perl - unmaintainable crap.  Blame the programmer, not the tool.  Any language can be made to suck.  Some just make you get creative in how badly you suck.

ANother C# example - guy at my work has a typed collection class.  Great, except it has a function called DisplayCollection.  Yes, this is present on the server - so some moron will eventually be popping up dialog boxes on the remoting server.  Also, he puts a try-catch-throw around every chunk of code, so he can debug into it easier through the IDE.  Don't even get me started on the GUI designer code ... that looks worse than most Perl code - even the crap.  Oh yeah, and the collection class also has a QueryCollection method ... and that gets sent to clients, which dont have oracle drivers.  Can't wait to see the day that a client barfs up an error about not being able to connect to the database.

Name: Anonymous 2007-02-03 10:17

>>25
I'm in favour of dynamic languages as well, just ones with sane syntax and no DWIM insanity. "DWIM" was the reason why I dropped Perl in favour of Python: too much insane rules to learn, and it can't be trusted because it WILL backfire when you least expect it.

I blame the programmer, but just because I know there are sucky programmers, I want to limit their impact, as I'll undoubtedly have to deal with their code in the real world.

Name: Anonymous 2007-02-03 12:11

pissing contest get

def factorize(n):
    is_prime = lambda n: not [x for x in xrange(2, int(n**0.5)+1) if n%x == 0]
    primes = []
    candidate = 2
    while not primes and candidate in xrange(2, n+1):
        if n % candidate == 0 and is_prime(candidate):
            primes = primes + [candidate] + factorize(n/candidate)
        candidate += 1
    return primes

Name: Anonymous 2009-01-14 12:28

LISP

Name: Anonymous 2009-01-14 12:34


#!/bin/sh
factors=$(factor $1)

Name: ​​​​​​​​​​ 2010-10-23 13:27

Name: Anonymous 2011-01-31 20:38

<-- check em dubz

Name: Anonymous 2011-02-03 2:15

Name: Anonymous 2011-02-04 14:53

Name: Sgt.Kabu鰳┊kiman⏑欤 2012-05-28 22:26

Bringing /prog/ back to its people
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy

Don't change these.
Name: Email:
Entire Thread Thread List