Performance of sequential stream - java-stream

I read the "when to use parallel stream?" by DougLea et.al http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html.
I wonder did any one had a guide lines(do's/ don't dos)/ observations which felt them that old way of coding is better in some cases than sequential stream?
I found one here https://jaxenter.com/java-performance-tutorial-how-fast-are-the-java-8-streams-118830.html
I know it's a abstract question but it will be helpful if somebody can share their experience in performance of seq stream vs java 7 way

I've done this just a few days ago; we had to sum a very large array and was wondering what would be the fastest way to do it - so I measured (don't guess; I've used jmh):
#State(Scope.Thread)
public static class Holder {
#Param({ "1000", "10000", "50000", "100000", "1000000" })
public int howManyEntries;
int array[] = null;
#Setup
public void setUp() {
array = new int[howManyEntries];
for (int i = 0; i < howManyEntries; ++i) {
array[i] = i;
}
}
#TearDown
public void tearDown() {
array = null;
}
}
#Fork(1)
#Benchmark
public int iterative(Holder holder) {
int total = 0;
for (int i = 0; i < holder.howManyEntries; ++i) {
total += holder.array[i];
}
return total;
}
#Fork(1)
#Benchmark
public int stream(Holder holder) {
return Arrays.stream(holder.array).sum();
}
#Fork(1)
#Benchmark
public int streamParallel(Holder holder) {
return Arrays.stream(holder.array).parallel().sum();
}
The winner is always the old style java-7 way.
// 1000=[iterative, stream, streamParallel]
// 10000=[iterative, stream, streamParallel]
// 50000=[iterative, stream, streamParallel]
// 100000=[iterative, stream, streamParallel]
// 1000000=[iterative, stream, streamParallel]
Even for 1 million elements. But the result differs in up to 60 ms - if that bites you or not is entirely your choice.
Streams are not meant for speed, they will not replace the old style, neither do they want to - it could add extra visibility to your code for example.

Related

dart: access function from list

Edit: i know, always call the first element on list, it isnt the point. i want to call numbers[0] func. and it regenerate new int.actually codes are not same which mine, i have a custom class which based on functions with random int and i need to use list of my custom class , so if i use func in list it will be awesome, how can i make new numbers list each time. when app start list regenerated, but i want when i call the list, it will regenerated
i want to print new int for each print but it prints same int , i tried so many thing and i cant figure out
void main{
int ramdomint(){
final _random = new Random();
int _num = _random.nextInt(100);
return _num;
}
List<int> numbers=[ramdomint(),ramdomint(),ramdomint()];
void printNums(){
for(var i=0;i<3;i++){
List<int> newNumbers =new List.from(numbers); //what can i use for this?
print(newNumbers[0]); //edit:i dont want [i], iwant to use ewNumbers[0] for new int for each time
}
}
printNums();
// expected new int for each but same one
}
solution from a friend:
import 'dart:math';
int get ramdomint => Random().nextInt(100);
List<int> get numbers => [ramdomint, ramdomint, ramdomint];
void main() {
for (var i = 0; i < 3; i++) {
print(numbers[0]);
}
}
Do not nest functions. Move ramdomint and printNums outside main function.
Add an empty list of arguments to the main function.
printNums: pass list of numbers as an argument.
printNums: you don't need to copy the list to the newNumbers if you want only to display the content of the list.
printNums: the problem is, you access only first element of the list (with 0 index).
import 'dart:math';
void main() {
List<int> numbers = [ramdomint(), ramdomint(), ramdomint()];
printNums(numbers);
}
int ramdomint() => Random().nextInt(100);
void printNums(List<int> numbers) {
// Easier way:
for (int item in numbers) {
print(item);
}
// Your way:
for (int i = 0; i < numbers.length; i++) {
print(numbers[i]);
}
}
EDIT:
According to #jamesdlin's comment, you can extend list class to randomize unique values in the list:
import 'dart:math';
void main() {
var numbers = <int>[]..randomize();
printNums(numbers);
}
void printNums(List<int> numbers) {
// Easier way:
for (int item in numbers) {
print(item);
}
// Your way:
for (int i = 0; i < numbers.length; i++) {
print(numbers[i]);
}
}
extension on List<int> {
void randomize({
int length = 3,
int maxValue = 100,
}) {
final generator = Random();
for (var i = 0; i < length; i++) {
add(generator.nextInt(maxValue));
}
}
}
The Problem here is that you are creating a list from the numbers list and accessing only the first element.
So it always prints the first element.
import 'dart:math';
void main() {
int ramdomint(){
final _random = new Random();
int _num = _random.nextInt(100);
return _num;
}
List<int> numbers=[ramdomint(),ramdomint(),ramdomint()];
void printNums(){
for(var i=0;i<3;i++){
print(numbers[i]);
}
}
printNums();
}
Don't want newNumbers, because it is already in List.
and the usage of List.from() - Documentation
Hope that works!

Stream Data Calculation In Flux

The following code illustrates a logic I need in a Spring Reactive project:
Inputs:
var period = 3;
int [] inArr = {2, 4, 6, 7, 9, 11, 13, 16, 17, 18, 20, 22 };
Calculation:
var upbond = inArr[0] + period;
var count =0;
List<Integer> result = new ArrayList();
for(int a: inArr){
if(a <= upbond){
count++;
}else{
result.add(count);
count = 1;
upbond += period;
}
}
result.add(count);
System.out.println(Arrays.toString(result.toArray()));
The data source of the sorted integers is the Flux from DB where it shall continually fetch data once a new suitable data is written into the DB. And the result shall be a stream that is sending out to another node through RSocket (by the request-stream communication mode).
After some online searching on Reactor, including some tutorials, I still can't figure out how to write the logic in the Flux fashion. The difficulty I have is that those calculations on data defined outside of the loop.
How shall I approach it in the Reactor?
The scan() variant that lets you use a separately typed accumulator is your friend here.
I'd approach this with a separate State class:
public class State {
private int count;
private Optional<Integer> upbond;
private Optional<Integer> result;
public State() {
this.count = 0;
this.upbond = Optional.empty();
this.result = Optional.empty();
}
public State(int count, int upbond) {
this.count = count;
this.upbond = Optional.of(upbond);
this.result = Optional.empty();
}
public State(int count, int upbond, int result) {
this.count = count;
this.upbond = Optional.of(upbond);
this.result = Optional.of(result);
}
public int getCount() {
return count;
}
public Optional<Integer> getUpbond() {
return upbond;
}
public Optional<Integer> getResult() {
return result;
}
}
...and then use scan() to build up the state element by element:
sourceFlux
.concatWithValues(0)
.scan(new State(), (state, a) ->
a <= state.getUpbond().orElse(a + period) ?
new State(state.getCount() + 1, state.getUpbond().orElse(a + period)) :
new State(1, state.getUpbond().orElse(a + period) + period, state.getCount())
)
.windowUntil(s -> s.getResult().isPresent())
.flatMap(f -> f.reduce((s1, s2) -> s1.getResult().isPresent()?s1:s2).map(s -> s.getResult().orElse(s.getCount() - 1)))
Aside: The concatWithValues() / windowUntil() / flatMap() bits are there to handle the last element - there's probably a cleaner way of achieving that, if I think of it I'll edit the answer.
I think scan is definitely the right tool here, combined with a stateful class, although my approach would be slightly different than Michaels.
Accumulator:
class UpbondAccumulator{
final Integer period;
Integer upbond;
Integer count;
Boolean first;
Queue<Integer> results;
UpbondAccumulator(Integer period){
this.period = period;
this.count = 0;
this.upbond = 0;
this.results = new ConcurrentLinkedQueue<>();
this.first = true;
}
//Logic is inside accumulator, since accumulator is the only the only thing
//that needs it. Allows reuse of accumulator w/o code repetition
public UpbondAccumulator process(Integer in){
//If impossible value
//Add current count to queue and return
//You will have to determine what is impossible
//Since we concat this value on the end of flux
//It will signify the end of processing
//And emit the last count
if(in<0){
results.add(count);
return this;
}
//If first value
//Do stuff outside loop
if(this.first) {
upbond = in + period;
first=false;
}
//Same as your loop
if(in <= upbond)
count++;
else {
results.add(count);
count = 1;
upbond += period;
}
//Return accumulator
//This could be put elsewhere since it isn't
//Immediately obvious that `process` should return
//the object but is simpler for example
return this;
}
public Mono<Integer> getResult() {
//Return mono empty if queue is empty
//Otherwise return queued result
return Mono.justOrEmpty(results.poll());
}
}
Usage:
dbFlux
//Concat with impossible value
.concatWithValues(-1)
//Create accumulator, process value and return
.scan(new UpbondAccumulator(period), UpbondAccumulator::process)
//Get results, note if there are no results, this will be empty
//meaning it isn't passed on in chain
.flatMap(UpbondAccumulator::getResult)
Following comment from Michael here is an immutable approach
Accumulator:
public class UpbondAccumulator{
public static UpbondState process(int period,Integer in,UpbondState previous){
Integer upbond = previous.getUpbond().orElse(in + period);
int count = previous.getCount();
if(in<0) return new UpbondState(upbond, count, count);
if(in <= upbond) return new UpbondState(upbond,count + 1 , null);
return new UpbondState(upbond + period, 1, count);
}
}
State object:
public class UpbondState {
private final Integer upbond;
private final int count;
private final Integer result;
public UpbondState() {
this.count = 0;
this.upbond = null;
this.result = null;
}
public UpbondState(Integer upbond, int count,Integer result) {
this.upbond = upbond;
this.count = count;
this.result = result;
}
public int getCount() { return count; }
public Optional<Integer> getUpbond() { return Optional.ofNullable(upbond); }
public Integer getResult() { return result; }
public boolean hasResult() { return result!=null; }
}
Usage:
dbFlux
.concatWithValues(-1)
.scan(new UpbondState(),
(prev, in) -> UpbondAccumulator.process(period,in,prev))
//Could be switched for Optional, but would mean one more map
//+ I personally think makes logic less clear in this scenario
.filter(UpbondState::hasResult)
.map(UpbondState::getResult)

Method declaration in java

I have a question regarding this code, you can see in some methods that there are comments with a return, that is because I think I have to use a return method instead of a void method. My teacher told me to transform them to a void class, but isn't a method which modifies field variables suposed to return something? I'm in doubt because sometimes my teacher seems to not know so much about programming or has some doubts so, thank for your help beforehand.
public class ArraysClass {
private int[] array;
private int arrayLength;
public ArraysClass() {
setArrayLength();
array = new int[arrayLength];
}
public int setArrayLength() {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter a number to set the length of the array:");
arrayLength = scanner.nextInt();
System.out.println();
return arrayLength;
}
public void fillArray() {
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < arrayLength; i++) {
System.out.println("Type a number to fill position " + i);
array[i] = scanner.nextInt();
}
// return array;
System.out.println();
}
public void findNumber() {
Scanner scanner = new Scanner(System.in);
int tofind, position;
System.out.println("Enter a number to search it in the array:");
tofind = scanner.nextInt();
position = Arrays.binarySearch(array, tofind);
if (position < 0) {
System.out.println("We did not find your number.");
} else {
System.out.println("The number you typed is in the next position: " + position);
}
System.out.println();
}
public void fillMethod() {
Scanner scanner = new Scanner(System.in);
int tofill;
System.out.println("Enter a number to fill the entire array with:");
tofill = scanner.nextInt();
Arrays.fill(array, tofill);
System.out.println();
//return array;
}
public void Sortmethod() {
Arrays.sort(array);
//return array;
}
private void showArray() {
System.out.println("Showing the array...");
for (int i = 0; i < arrayLength; i++) {
System.out.println(array[i]);
}
System.out.println();
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
ArraysClass arrayobj = new ArraysClass();
int choose;
do {
do {
System.out.println("1-Fill the array");
System.out.println("2-Find a number in the array");
System.out.println("3-Fill the entire array with a number");
System.out.println("4-Sort the array");
System.out.println("5-Show the array");
System.out.println("6-Exit");
System.out.println("Which one do you want to use?:");
choose = scanner.nextInt();
} while (choose < 1 && choose > 6);
switch (choose) {
case 1:
arrayobj.fillArray();
break;
case 2:
arrayobj.findNumber();
break;
case 3:
arrayobj.fillMethod();
break;
case 4:
arrayobj.Sortmethod();
break;
case 5:
arrayobj.showArray();
break;
case 6:
break;
}
} while (choose != 6);
}
}
In general, a method should return something if you need value from it. It is an approach used by some programmers to return a boolean even for do-only methods for success or failure or an int, for a status code. I do not follow these approaches. When I implement a method, I always ask myself how would I like to use that method. If I need a value from it, then it will have its type. Otherwise, it will be void. Let us see your methods:
setArrayLength: In general, from this name I would expect that you pass an int to it, representing the length and the method to be void. This is very common for setters, but here you are reading the actual value inside the method which is clearly inferior compared to having an int parameter, as your method will be useless if one wants to set the array length using a value not read from the console.
fillArray: I would expect this to be void, so I agree with its declaration, but again, the reading part should not be here.
findNumber: Should get the number to be found as a parameter and return an int, which represents its index, -1 if not found.
fillMethod: Should be void and should have an int parameter, which represents the value to be used to fill the array.
sortMethod: ok, maybe return the resulting array, but depends on your needs.
showArray: I would expect a PrintStream there, you will not necessarily output to System.out
General mistake: You mix methods with in/out operations to the console, the code is not general enough this way.

Using scanner to read phrases

Hey StackOverflow Community,
So, I have this line of information from a txt file that I need to parse.
Here is an example lines:
-> date & time AC Power Insolation Temperature Wind Speed
-> mm/dd/yyyy hh:mm.ss kw W/m^2 deg F mph
Using a scanner.nextLine() gives me a String with a whole line in it, and then I pass this off into StringTokenizer, which then separates them into individual Strings using whitespace as a separator.
so for the first line it would break up into:
date
&
time
AC
Power
Insolation
etc...
I need things like "date & time" together, and "AC Power" together. Is there anyway I can specify this using a method already defined in StringTokenizer or Scanner? Or would I have to develop my own algorithm to do this?
Would you guys suggest I use some other form of parsing lines instead of Scanner? Or, is Scanner sufficient enough for my needs?
ejay
oh, this one was tricky, maybe you could build up some Trie structure with your tokens, i was bored and wrote a little class which solves your problem. Warning: it's a bit hacky, but was fun to implement.
The Trie class:
class Trie extends HashMap<String, Trie> {
private static final long serialVersionUID = 1L;
boolean end = false;
public void addToken(String strings) {
addToken(strings.split("\\s+"), 0);
}
private void addToken(String[] strings, int begin) {
if (begin == strings.length) {
end = true;
return;
}
String key = strings[begin];
Trie t = get(key);
if (t == null) {
t = new Trie();
put(key, t);
}
t.addToken(strings, begin + 1);
}
public List<String> tokenize(String data) {
String[] split = data.split("\\s+");
List<String> tokens = new ArrayList<String>();
int pos = 0;
while (pos < split.length) {
int tokenLength = getToken(split, pos, 0);
tokens.add(glue(split, pos, tokenLength));
pos += tokenLength;
}
return tokens;
}
public String glue(String[] parts, int pos, int length) {
StringBuilder sb = new StringBuilder();
sb.append(parts[pos]);
for (int i = pos + 1; i < pos + length; i++) {
sb.append(" ");
sb.append(parts[i]);
}
return sb.toString();
}
private int getToken(String[] tokens, int begin, int length) {
if (end) {
return length;
}
if (begin == tokens.length) {
return 1;
}
String key = tokens[begin];
Trie t = get(key);
if (t != null) {
return t.getToken(tokens, begin + 1, length + 1);
}
return 1;
}
}
and how to use it:
Trie t = new Trie();
t.addToken("AC Power");
t.addToken("date & time");
t.addToken("date & foo");
t.addToken("Speed & fun");
String data = "date & time AC Power Insolation Temperature Wind Speed";
List<String> tokens = t.tokenize(data);
for (String s : tokens) {
System.out.println(s);
}

progress bar for http request - Blackberry

in my project i am using popupscreen with GaugeField for http request.Currently we are just incrementing the value of gaugefield with fixed rate and after http response we just remove the popupscreen. so some times http request is completed when gauge field is in 40% or 60%.
But i want to synchronize gaugefield value with http request/responses. it means that popupscreen will always remove at 100%.
I don't have the code in front of me, but I something similar in a project several years ago.
I wrote a subclass of InputStream that wrapped around the InputStream object I got back from openInputStream(), reimplementing all the read() methods so they would increment a counter with the number of bytes read. Whenever the counter reached a certain threshold, it would update a GaugeField object that was passed into the subclass's constructor.
So your subclass would look something like this:
public GaugedInputStream extends InputStream
{
private InputStream _inputStream = null;
private GaugeField _gaugeField = null;
private int _counter = 0;
private int _threshold = 0;
public void GaugedInputStream(InputStream inputStream, GaugeField gaugeField)
{
_inputStream = inputStream;
_gaugeField = gaugeField;
... other constructor stuff ...
}
public int read()
{
int byte = _inputStream.read();
increment(1);
return byte;
}
public int read(byte[] b)
{
int bytes = _inputStream.read(b);
increment(bytes);
return bytes;
}
public int read(byte[] b, int off, int len)
{
int bytes = _inputStream.read(b, off, len);
increment(bytes);
return bytes;
}
... override other InputStream methods here ...
private void increment(int bytes)
{
_counter = _counter + bytes;
_threshold = _threshold + bytes;
updateGaugeIfNeeded();
}
private void updateGaugeIfNeeded()
{
if (_threshold > 100)
{
updateGauge();
_threshold = 0;
}
}
private void updateGauge()
{
... code to update the gauge ...
}
}
I'm leaving out a lot of the guts here, but I hope this sets you in the right direction.

Resources