Are for-loops dead in 2019?

Are for-loops dead in 2019?

Attached: Java 8 Filter Map and Collect Example.png (640x277, 35K)

Other urls found in this thread:

pastebin.com/pZEeueKm
twitter.com/SFWRedditImages

No its still more readable, ergo better for small loops

>making three passes when one would suffice
So this is the power of functional programming?

what's the problem with an equivalent for loop?

java is an incredibly shit language.

Requires Android API 23 or higher so gg, can't even use it in your Android app

Just use kotlin or Rx to do the same thing

But yeah, old-school loops are fucking dead... At least they should be but some dicknoses at my office still love them

If you use parallelstream() instead of stream() you get free multithreading.

wow that looks stupid

Can I fizzbuzz with this?

If it actually made three passes it would be slower than a for loop, but it isn't.

That's pretty neat.

Yea first get a list of 1 - 100 then 3 map functions (or less) for the the fizz, buzz and fizzbuzz then another lambda for printing.

Shit is prob going to be slower then a regular for loop tho

It can't do it in parallel, numbers need to be converted before the filter condition.

How does it avoid multiple passes? Will it call map on a single element and then filter immediately?

Actually it's not only slower, it's a _LOT_ slower.

import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;

class Stream
{
public static void main(String[] args)
{
final int N = 10000000;
List strings = new ArrayList(N);
long before, after;

System.err.print("Generating random numbers... ");
before = System.currentTimeMillis();
for (int i = 0; i < N; ++i)
{
int n = (int) Math.random();
strings.add("" + n);
}
after = System.currentTimeMillis();
System.err.printf("%d ms\n", after - before);

System.err.print("For loop... ");
before = System.currentTimeMillis();
List evenFor = new ArrayList(strings.size());
for (String s: strings)
{
int i = Integer.valueOf(s);
if (i % 2 == 0)
{
evenFor.add(i);
}
}
after = System.currentTimeMillis();
System.err.printf("%d ms\n", after - before);

System.err.print("Stream + filter + collect... ");
before = System.currentTimeMillis();
List evenCollect = strings.stream()
.map(s -> Integer.valueOf(s))
.filter(i -> i % 2 == 0)
.collect(Collectors.toList());
after = System.currentTimeMillis();
System.err.printf("%d ms\n", after - before);
}
}


Generating random numbers... 3345 ms
For loop... 193 ms
Stream + filter + collect... 5433 ms

Attached: Screenshot 2019-08-27 at 19.16.49.png (2290x2106, 458K)

for me, its while

parallelStream does not make it considerably faster.

Generating random numbers... 3359 ms
For loop... 185 ms
parallelStream + filter + collect... 5304 ms

Attached: Screenshot 2019-08-27 at 19.24.01.png (2290x2106, 455K)

it'd fuse into a single pass in a proper FP language like Haskell

Math.random returns a float so (int) Math.random() is always 0 you fucking codemonkey

>what is fusion

Attached: 1540518175011.png (615x603, 145K)

java is disgustingly verbose

No, you dumb fucking retard.

>discussing Java
>b-b-b-but muh Haskell
Classic

Anyway, it's the call to collect that takes time.

System.err.print("parallelStream + filter, adding to an existing list... ");
before = System.currentTimeMillis();
List evenExist = new ArrayList(strings.size());
strings.parallelStream()
.map(s -> Integer.valueOf(s))
.filter(i -> i % 2 == 0)
.forEach(n -> evenExist.add(n));
after = System.currentTimeMillis();
System.err.printf("%d ms\n", after - before);


Generating random numbers... 3370 ms
For loop... 190 ms
parallelStream + filter + collect... 4970 ms
parallelStream + filter, adding to an existing list... 250 ms

>not using jmh

ignore this brainlet

this
compilers are more optimized for for loops

>moving the goal post
It doesn't matter, the second proposed method is slow as fuck.

Attached: mfw-caprice.jpg (541x498, 48K)

No not really even in newer languages like Kotlin (its what I know chill your language nazi ass) they have their uses. Right tool for the right job and personal preference. A developer that cant write a for loop is not one I would like to work with

>have no idea how to benchmark
>moving the goalposts

thanks for confirming

>taking the time is not a valid form of benchmarking because you must use this massive framework to do it
t. Enterprise Pajeet

What kind of Poo in Loo would argue that you need to install even more bloated Java shit in order to measure how bloated Java is?

So this is the power of java

a Sun certified weapon of Java

>claim that a certain approach is just as fast as another
>it actually isn't
>"it would be in haskell tho"

Attached: face-recursion.jpg (600x480, 56K)

java is the worst language
what are good languages? I like c but can you actually use this anywhere in the world today?

>I like c but can you actually use this anywhere in the world today?
C is frequently used in open source software that gotta go fast, or in systems and embedded programming.

It's actually really good for enterprise level things

So is C#

That's interesting, I wonder what's the reason for this.

It probably doesn't use ArrayList under the hood but rather some generic list which in this case leads to crap performance and/or is doing a deep copy somewhere.

It's still interesting to note that it takes almost twice as long as the for loop, which to me indicates that it is doing a double pass. That would make sense, since you need to convert the numbers first before you can run filter on it, and there's no guarantee that either method passed to map() or filter() doesn't modify stuff (so it needs to be sequential).

Have you heard about our lord and savior Haskell Curry?

Not disagreeing

> s -> Integer.valueOf(s)

Attached: yikes.png (1000x700, 101K)

you have to warm up the JVM by running it a few times, and only then measuring it.

why is his name bitchkov?

Some more interesting observations. I fixed what pointed out, and it seems like conversions are cached.

Yeah, I'm making a new version now.

I prefer if loops.

That's why Indians love it. Also Java is a name for a drink with laxative properties.

.collect(Collectors.toCollection(ArrayList::new))
This comes close to what the for loop does. I guess it's just that .toList() that kills everything, but looking at the implementation it's not that different:
return new CollectorImpl(
(Supplier) ArrayList::new,
List::add,
(left, right) -> { left.addAll(right); return left; },
CH_ID
);

Had to move code to pastebin, too big now. pastebin.com/pZEeueKm

Generating random numbers... 3713 ms
Warm up... 8450 ms
For loop... 266 ms
parallelStream + filter + collect... 487 ms
parallelStream + filter, adding to an existing list... 150 ms
For loop again... 574 ms


This is definitively not as expected, the for loop seems highly dependent on cached conversions.

Attached: Screenshot 2019-08-27 at 20.20.20.png (1020x322, 63K)

[int(i) for i in numbers.stream() if i % 2 == 0]

Python masterrace

class Stream
{
static long forLoop(List strings)
{
List list = new ArrayList(strings.size());
for (String s: strings) {
int i = Integer.valueOf(s);
if (i % 2 == 0) {
list.add(i);
}
}
return list.size();
}

static long collect(List strings)
{
List list = strings.parallelStream()
.map(s -> Integer.valueOf(s))
.filter(i -> i % 2 == 0)
.collect(Collectors.toCollection(ArrayList::new));
return list.size();
}

static long existing(List strings)
{
List list = new ArrayList(strings.size());
strings.parallelStream()
.map(s -> Integer.valueOf(s))
.filter(i -> i % 2 == 0)
.forEach(n -> list.add(n));
return list.size();
}

public static void main(String[] args)
{
final int N = 10000000;
final int iterations = 10;
List strings = new ArrayList(N);
long before, after;

System.err.print("Generating random numbers... ");
before = System.currentTimeMillis();
for (int i = 0; i < N; ++i) {
int n = (int) (Math.random() * 1000);
strings.add("" + n);
}
after = System.currentTimeMillis();
System.err.printf("%d ms\n", after - before);

for (int i = 0; i < iterations; ++i) {
System.err.printf("For loop (%d)... ", i);
before = System.currentTimeMillis();
forLoop(strings);
after = System.currentTimeMillis();
System.err.printf("%d ms\n", after - before);
}

for (int i = 0; i < iterations; ++i) {
System.err.printf("parallelStream collect (%d)... ", i);
before = System.currentTimeMillis();
collect(strings);
after = System.currentTimeMillis();
System.err.printf("%d ms\n", after - before);
}

for (int i = 0; i < iterations; ++i) {
System.err.printf("parallelStream existing list (%d)... ", i);
before = System.currentTimeMillis();
existing(strings);
after = System.currentTimeMillis();
System.err.printf("%d ms\n", after - before);
}
}
}

Attached: Screenshot 2019-08-27 at 20.29.53.png (684x1196, 219K)

>bloat

this is one of the better parts of the java ecosystem and is glaringly missing from others. In fact, one of the reasons to use java

...and also run into mysterious out-of-memory errors in production. Don't use parallelStream() unless you know you need it.

Poo’s favorite loo-analog is java

this, C++ is master race

That's not the same, you're performing i % 2 with a string, the python equivalent is much messier without something like the pipeline operator. Most people would probably do the conversion to int twice to make it look a bit cleaner.
list(filter(lambda n: n % 2 == 0, map(int, numbers))

missing a right parens you get the point though

No.

I just gave it some thought. Streams were a colossal mistake. We use it everywhere where I work now. Everywhere. Going through hundreds of thousands of elements.

Dear god. The performance is bad.

I don't know much about java, but is that list.add call in the "existing" method thread-safe?

You're not too bright, are you?

That's a good point. I didn't consider that. Thanks user.

You can do something like
void printStats(String description, Function method) {
System.err.print(description);
before = System.currentTimeMillis();
method.apply(strings);
after = System.currentTimeMillis();
System.err.printf("%d ms\n", after - before);
}
and call that with function references to avoid some of the repetition. Just pointing out since we seem to be discussing the power of functional Java. I still hate Java but it doesn't have to look worse than it is.

You should check if the results are the same using the plain for loop as a reference.

I did a big ol project on this. Might get fucked for posting sources here, but I can say for sure that parallelstreams will usually find itself marginally outclassed by using ForkJoinPool, ThreadPool, and a naive Threads implementation, particularly at around 4 threads, and suffers the most at thread oversaturation.
Hoooowever, the differences are really negligible when you compare them to a properly divided workload

>he thinks streams are the bottleneck rather than IO
lmao
if io isnt your bottleneck you shouldnt be using java anyways you fucking clown

so does it do 3 passes or not

Two passes and a deep copy.

The only problem related to stream performance that I'm aware of is that you can't always avoid wrapping primitive types in their corresponding objects. That's exactly what mapToInt etc. are for but it's not always possible to get there.

java streams only execute when collected. It's all managed in reverse; the only traversal, as it were, begins at the end and makes calls backwards towards the source.

Of course not. Streams are lazy and no intermediate collections are created (unless you use stateful operations such as .distinct() but that's unavoidable).

Should use a method reference:
.map(Integer::valueOf)
and should use a static import for the collector.
Also, alignment is off and that font is hideous.

ParallelStream has almost always worse performance than a regular stream.
Do you even Effective Java 3rd Edition (tm)?
You need some heavy ass processing to make it worth it to spin up a thread, not some stupid i % 2 == 0.

>Do you even Effective Java 3rd Edition (tm)?
Solid book recommendation. Should be mandatory for every Java dev out there.

Step aside, Pajeet.
let even = numbers.iter()
.map(|x| x.parse::().unwrap())
.filter(|x| x % 2 == 0)
.collect::();

SIR DO NOT MOCK JAVA IT IS SACRED LANGUAGE AND TOP WEAPON OF DURGASOFT IT DOES ALL THE NEEDFUL

Attached: 1550052861023.gif (849x458, 153K)

baiste

>Going through hundreds of thousands of elements
If it's that slow for your situation switch back to using a loop you dumb baby. Streams are simpler to write, read, and maintain in 99% of cases. And if your program was really that performance sensitive you wouldn't be using fucking java in the first place.

Not for the performance-minded. These methods are pretty expensive abstractions. Especially in languages like JS where they actually generate entirely new arrays each time, just to throw it away.

Good point.

pastebin.com/pZEeueKm

Initializing numbers...OK
Warming up...OK (n=10000000, m=50, t=23056)
forLoopA...OK (n=10000000, m=50, t=13988)
forLoopL...OK (n=10000000, m=50, t=21423)
existing...OK (n=10000000, m=50, t=13220)
collect...OK (n=10000000, m=50, t=14392)

forLoopA t=13988:
max=360
.99=360
.98=359
.95=347
.90=293
.80=284
.75=282
.50=276
.25=265
.20=263
.10=260
.05=258
.01=257
min=257

forLoopL t=21421:
max=975
.99=975
.98=941
.95=922
.90=853
.80=685
.75=541
.50=289
.25=281
.20=279
.10=277
.05=277
.01=274
min=274

existing t=13220:
max=348
.99=348
.98=341
.95=325
.90=304
.80=270
.75=267
.50=255
.25=252
.20=249
.10=249
.05=246
.01=243
min=243

collect t=14392:
max=355
.99=355
.98=353
.95=353
.90=323
.80=302
.75=288
.50=280
.25=272
.20=270
.10=269
.05=269
.01=265
min=265

truly the ICON of JAVA. Every blog and forum around the globe will represent DURGA SOFT as pioneer and leader in Java Certification training. When the discussion comes on Java, all the online communities will have only one word DURGA SOFT

Do zoomers really hate writing for/while loops nowadays

>using '+' as a shorthand for "plus", meaning in conjunction with
And the title misrepresents the order of operations in the example code. Fucking brainlet coders.

In decent languages with zero-cost abstractions like Rust, functional iterator methods are just as efficient as dumb ancient C-style for loops.

>zero-cost abstractions

Attached: Screenshot from 2019-08-28 02-09-30.png (1381x460, 104K)

Let's see the equivalent for loop

ok

Attached: Screenshot from 2019-08-28 02-18-17.png (1054x247, 36K)

"""""zero-cost abstractions""""

Attached: Screenshot from 2019-08-28 02-34-36.png (1004x602, 107K)

I don't know how it works in Java, but in a good language that won't be the same as three loops.
In python for example, there's a reason that map produces a map object and filter produces a filter object rather than a list.

it's not about the compiler optimizing it, it's how Java implemented the functional interfaces.
Under the hood, it's an object. It's syntax sugar. Every single time you use a lambda in Java, it creates a new anonymous class, creates a new instance of that anonymous class, then passes it to that function.

It's fucking slow because that simple map/filter/collect in the OP is 2 new classes, 4 new objects.

zero cost abstractions

Attached: Screen Shot 2019-08-27 at 9.00.53 PM.png (1245x425, 78K)

Attached: Screen Shot 2019-08-27 at 9.01.28 PM.png (1243x640, 115K)

What are you trying to achive, low Q cnile? You DO realize the Rust code actually understands unicodes, right?

Retard boomer cnile, I have not found 1 (ONE) cnile in Jow Forums who knows what he's talking about. Smarter people likes solving problems, not memory management.

Attached: Screenshot from 2019-08-28 12-08-23.png (3154x796, 131K)

How made are you that your toy language can't reduce a simple expression to c == 'a'?

I was not sure what numbers.stream() did, I assumed it was an int generator. I actually prefer to use map, filter, reduce in most of my code at work because it's more comprehensible than list comprehensions for people that are used to functional constructs, but whipping a cool list comprehension one-liner is still pretty awesome.

If you want to iterate over unicode code points, use chars(), otherwise don't be retarded and use c=='a'? chars() is not what you think it is, cnile retard. Your alternative here falls apart the moment you provide a non-ascii strings because C doesn't understand UTF-8

>MORE LINES BAD

Attached: 1547998446687.png (882x1025, 246K)

You're literally just reguritating someone else who said that, but out of context?
More line is worse especially when not only it's longer, but expresses a whole different class of complexity to solve the same problem.

I'm calling out your lack of knowledge. Counting ASM lines is the dumbest possible performance comparison you can make. Learn assembly.

It doesn't take a genius to guess comparing a register to a constant value in a few instruction takes a few cycles at most while 500 lines of branching and allocation is going to be way slower.
Now I know you're just baiting at this point.

>actually works
fails in utf strings

Ah yes, a typical C program. Crashing and burning and returning invalid results is fine but MUUUH GODBOLT OUTPUT CIRCLEJERK!!!1!

Attached: 1550271164411.png (387x550, 339K)