Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #34952 > unrolled thread

Re: So I did "FizzBuzz", in Java!

Started byDaniel Pitts <usenet@coloraura.com>
First post2016-07-18 09:26 -0700
Last post2016-07-18 19:46 -0400
Articles 11 — 5 participants

Back to article view | Back to comp.lang.java.programmer

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: So I did "FizzBuzz", in Java! Daniel Pitts <usenet@coloraura.com> - 2016-07-18 09:26 -0700
    Re: So I did "FizzBuzz", in Java! Eric Douglas <e.d.programmer@gmail.com> - 2016-07-18 10:10 -0700
      Re: So I did "FizzBuzz", in Java! Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-07-18 14:09 -0400
        Re: So I did "FizzBuzz", in Java! Eric Douglas <e.d.programmer@gmail.com> - 2016-07-18 14:00 -0700
          Re: So I did "FizzBuzz", in Java! Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-07-18 17:30 -0400
            Re: So I did "FizzBuzz", in Java! Eric Douglas <e.d.programmer@gmail.com> - 2016-07-19 05:06 -0700
              Re: So I did "FizzBuzz", in Java! Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-07-19 08:13 -0400
                Re: So I did "FizzBuzz", in Java! Eric Douglas <e.d.programmer@gmail.com> - 2016-07-19 05:18 -0700
          Re: So I did "FizzBuzz", in Java! Martin Gregorie <martin@address-in-sig.invalid> - 2016-07-18 21:59 +0000
          Re: So I did "FizzBuzz", in Java! Arne Vajhøj <arne@vajhoej.dk> - 2016-07-18 19:51 -0400
    Re: So I did "FizzBuzz", in Java! Arne Vajhøj <arne@vajhoej.dk> - 2016-07-18 19:46 -0400

#34952 — Re: So I did "FizzBuzz", in Java!

FromDaniel Pitts <usenet@coloraura.com>
Date2016-07-18 09:26 -0700
SubjectRe: So I did "FizzBuzz", in Java!
Message-ID<nmj00i$jae$1@dont-email.me>
On 7/17/16 8:49 AM, Stefan Ram wrote:
>   I don't know if you have heard of »FizzBuzz«. Otherwise
>   a web search might explain it to you:
>
>       »Write a program that prints the numbers from 1 to 100.
>       But for multiples of three print "Fizz" instead of the
>       number and for the multiples of five print "Buzz". For
>       numbers which are multiples of both three and five print
>       "FizzBuzz"«.
>
>   Allegedly it's used to test job applicants and allegedly
>   even programmers with university degrees in the field fail
>   to be able to program it.
>
>   I have read about it for years, but today I did write it.
>
>   My solution tries to avoid code repetitions and to be
>   run-time efficient. It's not the smallest solution when
>   the code size is taken into account.
>
> public final class Main
> { public static void main( final java.lang.String[] args )
>   { final java.lang.String eol = java.lang.System.lineSeparator();
>     final java.lang.StringBuilder builder
>     = new java.lang.StringBuilder( 1024 );
>     final java.lang.String fizz     = "Fizz"     + eol;
>     final java.lang.String     buzz =     "Buzz" + eol;
>     final java.lang.String fizzbuzz = "FizzBuzz" + eol;
>     for( int i = 1; i < 101; ++i )
>     { final boolean d3 = i % 3 == 0;
>       final boolean d5 = i % 5 == 0;
>       final boolean db = d3 && d5;
>            if( db )builder.append( fizzbuzz );
>       else if( d3 )builder.append( fizz );
>       else if( d5 )builder.append( buzz );
>       else         { builder.append( i ); builder.append( eol ); }}
>     java.lang.System.out.println( builder ); }}
>
>   I did not avoid to have the string literal »"FizzBuzz"«,
>   even though one might have combined that from the strings
>   »Fizz« and »Buzz«, which are already there, but to do so
>   might be no real improvement.
>
Here's one of my solutions:

public final class FizzBuzz {
     public static void main(final java.lang.String[] args) {
         java.util.stream.IntStream
             .rangeClosed(1, 100)
             .mapToObj(i -> {
                 final StringBuilder result = new StringBuilder();
                 if (0 == i % 3) {
                     result.append("Fizz");
                 }
                 if (0 == i % 5) {
                     result.append("Buzz");
                 }
                 if (result.length() == 0) {
                     result.append(i);
                 }

                 return result;
             }).forEachOrdered(System.out::println);
     }
}

[toc] | [next] | [standalone]


#34953

FromEric Douglas <e.d.programmer@gmail.com>
Date2016-07-18 10:10 -0700
Message-ID<1933e39b-6363-4174-8392-602415a61799@googlegroups.com>
In reply to#34952
On Monday, July 18, 2016 at 12:27:08 PM UTC-4, Daniel Pitts wrote:
> Here's one of my solutions:
> 
> public final class FizzBuzz {
>      public static void main(final java.lang.String[] args) {
>          java.util.stream.IntStream
>              .rangeClosed(1, 100)
>              .mapToObj(i -> {
>                  final StringBuilder result = new StringBuilder();
>                  if (0 == i % 3) {
>                      result.append("Fizz");
>                  }
>                  if (0 == i % 5) {
>                      result.append("Buzz");
>                  }
>                  if (result.length() == 0) {
>                      result.append(i);
>                  }
> 
>                  return result;
>              }).forEachOrdered(System.out::println);
>      }
> }

That sounds real fancy.  Is it really more efficient than a basic loop?
public final class FizzBuzz { 
     public static void main(final java.lang.String[] args) { 
         for (int i = 1; i <= 100; i++) { 
                 final StringBuilder result = new StringBuilder(); 
                 if (0 == i % 3) { 
                     result.append("Fizz"); 
                 } 
                 if (0 == i % 5) { 
                     result.append("Buzz"); 
                 } 
                 if (result.length() == 0) { 
                     result.append(i); 
                 } 
             }
     } 
}

[toc] | [prev] | [next] | [standalone]


#34954

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2016-07-18 14:09 -0400
Message-ID<nmj61j$95o$1@dont-email.me>
In reply to#34953
On 7/18/2016 1:10 PM, Eric Douglas wrote:
> On Monday, July 18, 2016 at 12:27:08 PM UTC-4, Daniel Pitts wrote:
>> Here's one of my solutions:
>> [... using streams ...]
>
> That sounds real fancy.  Is it really more efficient than a basic loop?
> public final class FizzBuzz {
>      public static void main(final java.lang.String[] args) {
>          for (int i = 1; i <= 100; i++) {
>                  final StringBuilder result = new StringBuilder();
>                  if (0 == i % 3) {
>                      result.append("Fizz");
>                  }
>                  if (0 == i % 5) {
>                      result.append("Buzz");
>                  }
>                  if (result.length() == 0) {
>                      result.append(i);
>                  }
>              }
>      }
> }

     1) The streams-based solution is gazillions of times slower
than your basic loop.

     2) Your basic loop is gazillions of times faster than ...
a correct solution.  (Ponder this a while.)

     3) This is not the first "efficiency" question you've asked, which
leads me to fear that you may be well on the way to becoming an addict.
Stop!  Stop now, while you still can!  "Efficiency" is a drug as habit-
forming and as destructive as anything you can find in a darkened back
alley.  If you get hooked, you'll never get clean.  Trust me, I know:
The monkey has ridden my back for half a century despite my strenuous
efforts to dislodge it.  Don't follow my pathway to ruin!

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#34959

FromEric Douglas <e.d.programmer@gmail.com>
Date2016-07-18 14:00 -0700
Message-ID<cc1c596f-a043-4ba7-9e55-b98fc12cc89c@googlegroups.com>
In reply to#34954
On Monday, July 18, 2016 at 2:10:07 PM UTC-4, Eric Sosman wrote:
>      3) This is not the first "efficiency" question you've asked, which
> leads me to fear that you may be well on the way to becoming an addict.
> Stop!  Stop now, while you still can!  "Efficiency" is a drug as habit-
> forming and as destructive as anything you can find in a darkened back
> alley.  If you get hooked, you'll never get clean.  Trust me, I know:
> The monkey has ridden my back for half a century despite my strenuous
> efforts to dislodge it.  Don't follow my pathway to ruin!

It depends how big the efficiency problem is and how many places it's used.  If you're saving a few seconds it may not be an issue, unless that code is called many times.
I worked for one of the largest retailers in the world and we had some major performance issues.  One program we'd get down to under an hour, the initial contractors wrote to run over 8 hours..

[toc] | [prev] | [next] | [standalone]


#34960

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2016-07-18 17:30 -0400
Message-ID<nmjhqe$jj6$1@dont-email.me>
In reply to#34959
On 7/18/2016 5:00 PM, Eric Douglas wrote:
> On Monday, July 18, 2016 at 2:10:07 PM UTC-4, Eric Sosman wrote:
>>      3) This is not the first "efficiency" question you've asked, which
>> leads me to fear that you may be well on the way to becoming an addict.
>> Stop!  Stop now, while you still can!  "Efficiency" is a drug as habit-
>> forming and as destructive as anything you can find in a darkened back
>> alley.  If you get hooked, you'll never get clean.  Trust me, I know:
>> The monkey has ridden my back for half a century despite my strenuous
>> efforts to dislodge it.  Don't follow my pathway to ruin!
>
> It depends how big the efficiency problem is and how many places it's used.[...]

     Right.  Which means you must measure *before* fiddling around,
most especially before micro-fiddling.

     - If you don't measure, you don't actually know whether you
       have a problem.

     - If you don't measure, you won't know whether any changes you
       make are helpful or hurtful.

     - If you decide a `for' loop is more efficient than an IntStream,
       based on no evidence whatsoever, you're just thrashing around.

     - Even if you have measurements in hand that demonstrate one is
       more efficient than the other, bear in mind that the iteration
       count of O-N-E  H-U-N-D-R-E-D (!!!) is so small that any
       conceivable difference will be noise.

     - Finally, observe that by transforming a correct program from
       IntStream to `for' loop you produced an *incorrect* program!
       Faster, yes (even without measurement I'm confident of that),
       but incorrect nonetheless.  What price "efficiency," hmm?

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#34972

FromEric Douglas <e.d.programmer@gmail.com>
Date2016-07-19 05:06 -0700
Message-ID<d30c2b2f-0471-4231-9867-19126e5edc13@googlegroups.com>
In reply to#34960
On Monday, July 18, 2016 at 5:31:03 PM UTC-4, Eric Sosman wrote:
>      - Finally, observe that by transforming a correct program from
>        IntStream to `for' loop you produced an *incorrect* program!
>        Faster, yes (even without measurement I'm confident of that),
>        but incorrect nonetheless.  What price "efficiency," hmm?

Who me bad code?  I just tested the code I modified and it runs fine.  It's just missing the print requirement.

public final class FizzBuzz { 
     public static void main(final java.lang.String[] args) { 
         for (int i = 1; i <= 100; i++) { 
                 final StringBuilder result = new StringBuilder(); 
                 if (0 == i % 3) { 
                     result.append("Fizz"); 
                 } 
                 if (0 == i % 5) { 
                     result.append("Buzz"); 
                 } 
                 if (result.length() == 0) { 
                     result.append(i); 
                 } 
                 java.lang.System.out.println( result );
             } 
     } 
}

I ran the IntStream version 3 times with a timer.  It took 5762, 5817, 5826 milliseconds to go through 1 to 1,000,000.
I ran this for loop 1 to 1,000,000 with the same timer 3 times.  It took 5715, 5803, 5685 milliseconds.

So yes it is faster without the fancy IntStream.  Is it worth changing production code?  It would have to be really heavily used to get noticeable savings on the performance.  Is it more readable/maintainable?  I think that is a much more important question when performance is very similar and functionality remains the same.

[toc] | [prev] | [next] | [standalone]


#34973

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2016-07-19 08:13 -0400
Message-ID<nml5ih$l1b$1@dont-email.me>
In reply to#34972
On 7/19/2016 8:06 AM, Eric Douglas wrote:
> On Monday, July 18, 2016 at 5:31:03 PM UTC-4, Eric Sosman wrote:
>>      - Finally, observe that by transforming a correct program from
>>        IntStream to `for' loop you produced an *incorrect* program!
>>        Faster, yes (even without measurement I'm confident of that),
>>        but incorrect nonetheless.  What price "efficiency," hmm?
>
> Who me bad code?  I just tested the code I modified and it runs fine.  It's just missing the print requirement.

     BINGO!

     Now: If you have a program X that produces correct output, and a
program Y that produces no output, you will notice the defect in Y
the first time you run it.  You will then modify Y to produce Z, which
runs and produces the correct output.

     Question: How fast must Z be to ensure that the combined running
time of Y plus Z is less than that of X?

     ... and that's what I mean about the "price" of efficiency.  The
single unproductive run of Y has already dissipated more time than
the X minus Z speedup can recoup.

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#34975

FromEric Douglas <e.d.programmer@gmail.com>
Date2016-07-19 05:18 -0700
Message-ID<ec30d6bb-6a64-48a1-a714-ae494539715c@googlegroups.com>
In reply to#34973
On Tuesday, July 19, 2016 at 8:14:20 AM UTC-4, Eric Sosman wrote:
>      Now: If you have a program X that produces correct output, and a
> program Y that produces no output, you will notice the defect in Y
> the first time you run it.  You will then modify Y to produce Z, which
> runs and produces the correct output.
> 
>      Question: How fast must Z be to ensure that the combined running
> time of Y plus Z is less than that of X?
> 
>      ... and that's what I mean about the "price" of efficiency.  The
> single unproductive run of Y has already dissipated more time than
> the X minus Z speedup can recoup.

What if it just leads you to question the requirements?  You find that the print requirement was actually generating a 100 page daily report no one really needed.  The program could simultaneously run faster and save trees by saving the data electronically instead.

[toc] | [prev] | [next] | [standalone]


#34961

FromMartin Gregorie <martin@address-in-sig.invalid>
Date2016-07-18 21:59 +0000
Message-ID<nmjjft$htm$1@dont-email.me>
In reply to#34959
On Mon, 18 Jul 2016 14:00:26 -0700, Eric Douglas wrote:

> On Monday, July 18, 2016 at 2:10:07 PM UTC-4, Eric Sosman wrote:
>>      3) This is not the first "efficiency" question you've asked, which
>> leads me to fear that you may be well on the way to becoming an addict.
>> Stop!  Stop now, while you still can!  "Efficiency" is a drug as habit-
>> forming and as destructive as anything you can find in a darkened back
>> alley.  If you get hooked, you'll never get clean.  Trust me, I know:
>> The monkey has ridden my back for half a century despite my strenuous
>> efforts to dislodge it.  Don't follow my pathway to ruin!
> 
> It depends how big the efficiency problem is and how many places it's
> used.  If you're saving a few seconds it may not be an issue, unless
> that code is called many times.
> I worked for one of the largest retailers in the world and we had some
> major performance issues.  One program we'd get down to under an hour,
> the initial contractors wrote to run over 8 hours..

on my laptop, which runs Linux (Fedora 23) on a 1.6GHz Core Duo, Daniel's 
code took about twice the elapsed time and used twice the mill time (both 
user and system mill) as a FizzBuzz version I made which uses a counted 
for loop to drive it. I was careful to use exactly the same logic as 
Daniel used inside the loop and the same lifetime for each StringBuilder 
instance.

I've now added a command line parameters so I can run much longer series
The looped version remains fastest at up to 100,000 tries, but not by so 
much:

100     numbers    Original    looped
        real time     .399s     .205s
        user cpu      .480s     .188s
        system cpu    .055s     .027s

100,000 numbers    Original    looped
        real time     .901s     .687s
        user cpu     1.382s     .934s
        system cpu    .143s     .125s

I'm really intrigued, though by the way that the cpu usage increases more 
for the looped code than for Daniel's original.

Here's my code:

public class FizzBuzz2
{
   public static void main(String[] args)
   {
      int n = 100;      
      if (args.length > 0)
         n = Integer.parseInt(args[0]);
      System.out.println("Run from 1 to " + n);
      for (int i = 1; i <= n; i++)
      {
         StringBuilder result = new StringBuilder();
         if (0 == i % 3)
            result.append("Fizz");
         if (0 == i % 5)
            result.append("Buzz");
         if (result.length() == 0)
            result.append(i);
         System.out.println(result.toString());
      }
   }
}


-- 
martin@   | Martin Gregorie
gregorie. | Essex, UK
org       |

[toc] | [prev] | [next] | [standalone]


#34965

FromArne Vajhøj <arne@vajhoej.dk>
Date2016-07-18 19:51 -0400
Message-ID<nmjq2i$1ejm$1@gioia.aioe.org>
In reply to#34959
On 7/18/2016 5:00 PM, Eric Douglas wrote:
> On Monday, July 18, 2016 at 2:10:07 PM UTC-4, Eric Sosman wrote:
>> 3) This is not the first "efficiency" question you've asked, which
>> leads me to fear that you may be well on the way to becoming an
>> addict. Stop!  Stop now, while you still can!  "Efficiency" is a
>> drug as habit- forming and as destructive as anything you can find
>> in a darkened back alley.  If you get hooked, you'll never get
>> clean.  Trust me, I know: The monkey has ridden my back for half a
>> century despite my strenuous efforts to dislodge it.  Don't follow
>> my pathway to ruin!
>
> It depends how big the efficiency problem is and how many places it's
> used.  If you're saving a few seconds it may not be an issue, unless
> that code is called many times. I worked for one of the largest
> retailers in the world and we had some major performance issues.  One
> program we'd get down to under an hour, the initial contractors wrote
> to run over 8 hours..

Question: how large a portion of the application did you have to
change to achieve that? Most likely less than 1%.

Optimization is something you do when you:
- have noticed a real problem due to bad performance
- have identified the specific cause of the bad performance

Arne


[toc] | [prev] | [next] | [standalone]


#34964

FromArne Vajhøj <arne@vajhoej.dk>
Date2016-07-18 19:46 -0400
Message-ID<nmjpok$1e1d$2@gioia.aioe.org>
In reply to#34952
On 7/18/2016 12:26 PM, Daniel Pitts wrote:
> Here's one of my solutions:
>
> public final class FizzBuzz {
>     public static void main(final java.lang.String[] args) {
>         java.util.stream.IntStream
>             .rangeClosed(1, 100)
>             .mapToObj(i -> {
>                 final StringBuilder result = new StringBuilder();
>                 if (0 == i % 3) {
>                     result.append("Fizz");
>                 }
>                 if (0 == i % 5) {
>                     result.append("Buzz");
>                 }
>                 if (result.length() == 0) {
>                     result.append(i);
>                 }
>
>                 return result;
>             }).forEachOrdered(System.out::println);
>     }
> }

I also think that one would have questionable value in
an interview situation.

It does show good knowledge of Java especially Java 8.

But it is not the simplest and most maintainable approach.

Arne

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web