I need to make a new ForkJoinTask for every division, and don't know how to get to the next position in the array. Can someone help me?
protected static double parManyTaskArraySum(final double[] input, final int numTasks) {
double sum = 0;
// ToDo: Start Calculation with help of ForkJoinPool
ForkJoinPool fjp = new ForkJoinPool(numTasks);
fjp.execute(() -> {
sum+=( 1 / input[???] ); //the problem is here
});
return sum;
}
Exception: local variables referenced from a lambda expression must be final or effectively final
You are feeding a Runnable lambda to your ForkJoinPool.
As such, you cannot parametrize it with the desired array chunk.
You should actually define a class extending RecursiveTask<Double> whose constructor takes the array chunk as parameter, and decides whether to operate on the whole of it or fork if it's too large.
Then use the invoke method of your ForkJoinPool to get the result of the final calculation, by passing it a new instance of that RecursiveTask<Double> taking the whole array (the task will the decide based on your criteria whether to do everything in one go, or to fork, say, half of the array's elements to another task and join later).
Note as there is some confusion here.
If in fact, you don't need to leverage the fork/join framework and only want to perform your operation asynchronously, there are many ways to do so without a ForkJoinPool.
For instance:
Callable<Double> call = () -> {return Arrays.stream(input).sum();};
Future<Double> future = Executors.newSingleThreadExecutor().submit(call);
// when you're ready
Double sum = future.get();
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
hello i a trying to compare to values after i apply a lambda experrsion to them im trying to compare a location of a player and another to see the distance between them and im having trouble with lambdas
public class mathprob {
public static void main(String[] args) {
}
Location loc = player.getlocation();
Location newloc = player.getlocation();
(loc, newloc) -> Math.pow((loc.getX()-newloc.getX()), 2) +
Math.pow(loc.getY()-newloc.getY(), 2)+Math.pow(loc.getZ()-
newloc.getZ(),
2));
}
i keep getting a error because the lambda is incorrect i dont know how to use a lambda in this situation and then comparing the two values to each other (loc, newloc) the two values or two points P1(loc.getX(), loc,getY(), loc.getZ()) and P2(newloc.getX(), newloc.getY(), newloc.getZ()) i wanna compare the x and the y and the z of each point to see the number gap between them
Lambdas are just a way to create a type for a function. Keep in mind that a function has no "values" and hasn't been executed yet.
You can apply any Lambda to a set of values by calling it's apply method. It will then take the inputs (parameters to apply) and return the value as the result. A Lambda for a function that looks like this
(Coordinate x) -> { return new Distance(Math.sqrt(x.x * x.x + x.y * x.y)) }
would return the distance to the origin for a Coordinate assuming a Coordinate looked a little like
public class Coordinate {
public double x;
public double y;
}
and Distance looked a bit like like
public class Distance {
public Distance(double value) {
... whatever the implementation is ...
}
}
This function has a type conversion in it, it takes a Coordinate and returns a Distance. This means it fits the java "interface" of
Function<Coordinate, Distance>
and just by writing this Lambda
(Coordinate x) -> { return new Distance(Math.sqrt(x.x * x.x + x.y * x.y)) }
The Java compiler will generate some unnamed class of type Function<Coordinate, Distance> and instantiate an instance (create an object the class) to use in the context of the location of the Lambda.
Now if that lambda is within a method of a stream, such that the stream's parameter types are compatible, the stream will (in some manner) call apply on each value the stream is handling. Those values come from a Supplier which is basically an object that has a T get() method.
Stream calls the Supplier's get() method.
Stream has a method .forEach( ... ) containing a lambda that consumes the get() type.
Stream applies the value of get() to the lambda in forEach() by passing it into apply(value).
Stream collects the result of apply(value)
Stream returns from the .forEach(...) method a new stream with values typed to match the return value of the lambda in the forEach() method.
Eventually, these values are passed into a Collector method which combines values into some sort of buffer. Sometimes a List, sometimes a single value.
Conveniences exist for various ways of simplifying the collectors. Conveniences exist for generating values without coding suppliers.
The lambda syntax itself is a convenience for not having to write an implementation of one of the "xxxFunction" interfaces, create an object of it, and pass it into the stream.
Predicates are what they call Functions that return boolean values. There are even more convenience functions that work with predicates.
So, if you don't have a collection of data points to process, you probably shouldn't be using lambdas. If you do have a collection of data points to process, then keep in mind that streams and lambdas provide a new not-quite-like-a-loop way of processing them. They are guaranteed to be applied to all values, but the order of their application is not necessarily in the strong ordering that a traditional loop would apply. With the right options, you can effectively split the input into multiple chunks (spliterator vs iterator) and process the data in parallel.
Now that you have a quick overview of Lambdas, Streams, and the Functional interfaces, you can see that
(loc, newloc) -> Math.pow((loc.getX()-newloc.getX()), 2) +
Math.pow(loc.getY()-newloc.getY(), 2)+Math.pow(loc.getZ()-newloc.getZ(),
2));
wouldn't "do" anything, because at best it describes this
public class MyFunction implements Function<Location, Location, Double> {
Double apply(Location first, Location second) {
return Math.pow((first.getX()-second.getX()), 2)
+ Math.pow(first.getY()-second.getY(), 2)
+ Math.pow(first.getZ()-second.getZ(), 2)
}
}
MyFunction myFunc = new MyFunction();
Which has the following problem"
It's a coding error as it's only creating the facility to transform locations, and never using it.
Using the facility would look like
double result = myFunc.apply(loc, newloc);
Now, the very astute readers will mention auto-boxing, but in reality the compiler would choose the ToDoubleBiFunction type, probably side-stepping some of the possible auto-boxing issues. I just didn't want to write the example up in the non-generic manner, as again, the primitive functional types are a convenience (and optimization) of the general "all object" description above.
Lambda expressions are used to generate anonymous functions. They can be used where a #FunctionalInterface is expected.
Read more about them here: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
If you'd like your code to work you can assign your lambda to a BiFunction variable and then execute it passing in the loc and newloc.
public class mathprob {
public static void main(String[] args) {
Location _loc = player.getlocation();
Location _newloc = player.getlocation();
BiFunction<Location, Location, Double> lambdaExpression = (loc, newloc) -> {
return Math.pow((loc.getX()-newloc.getX()), 2) +
Math.pow(loc.getY()-newloc.getY(), 2)+Math.pow(loc.getZ()-newloc.getZ(),
2);
};
double result = lambdaExpression.apply(_loc, _newloc);
}
}
Here is an example of how the equivalent method declaration would look like instead of using a lambda:
public class mathprob {
public static void main(String[] args) {
Location loc = player.getlocation();
Location newloc = player.getlocation();
double result = calculate(loc, newloc);
}
public static double calculate(Location loc, Location newloc) {
return
Math.pow((loc.getX() - newloc.getX()), 2) +
Math.pow(loc.getY() - newloc.getY(), 2) +
Math.pow(loc.getZ() - newloc.getZ(), 2);
}
}
Read the 14.5. Statements from JLS.
value;
is not a valid statement, as
"text"; or 5; are not.
Lambda Expression is a value, which constitutes an anonymous method, and which can be assigned to the variable (of Functional Interface type) or can be passed into method, as an ordinary argument value.
public void someMethod() {
5; //does not compile, as this is not a statement.
int x = 5; //compiles, as this is a statement.
//Similarly,
() -> System.out.println("Hi"); //does not compile, as this is not a statement
Runnable r1 = () -> System.out.println("Hi"); //compiles, as this is a statement
}
Assuming I have a list of 100 strings. Is there a difference between the following two approaches in performance (or any other difference)
1.
List<String> myList = Arrays.asList("s1", "s2", "s3"....."s100");
foo(myList);
private void foo(List<String> myList) {
// logic to choose 2 strings from the list
//do something with -- str1 and str2
}
2.
List<String> myList = Arrays.asList("s1", "s2", "s3"....."s100");
// logic to choose 2 strings from the list
foo(str1, str2);
private void foo(String myStr1, String myStr2) {
//do something with -- myStr1 and myStr2
}
Since Java passes the reference(as values) of the List or individual Strings I am assuming those arguments will just hold (copies of) references/addresses. So I am leaning towards passing the entire list.
The above will be a utility method and I want to put the 'logic to choose 2 strings from the list' inside the foo method so callers don't have to repeat that logic before calling; but I am concerned about sending a large list as argument.
Thanks for help.
** Edit :**
Yes I am looking for Performance concerns.
And List<String> probably wasn't the correct example. Think of it as a Map<String,Long> (City,Temperature). And the logic will be to always choose Chicago and LA and foo will operate on the temperatures. Note that this logic will always be the same and callers would just repeat the same code in approach #2.
I recommend you ignore potential difference in performance (which would be negligible in this case) and focus entirely on clarity of your code. In other words, the question is not which is more efficient but which better reflects the intention of the method you are calling. If foo is a method which would naturally expect two arguments (such as storeFullName) then it should be passed two arguments. If it would naturally expect to select two values from a list (such as printTwoLongestStrings) then it should take a collection.
You might also consider the principle of giving each method a single responsibility. In that case it might make sense to have separate methods for selecting the two values and doing something with them:
Pair<String, String> longestPair = getTwoLongestStrings(list);
printStrings(longestPair);
** Edit **
Your question has clarified that you are focused specifically on performance and you provided more detail of your use case. Specifically you are asking if there is a difference in performance in passing a list or two values to a method. Yes there is a difference. I ran a trial calling an empty function 10 billion times with two String arguments and with a list. The list call took 24 secs and the separate argument call took 13 secs. It's likely that other physical hardware will show different results. It's also possible that JVM optimisation is not making this a fair test.
public class PerfTest {
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "b");
long time1 = System.currentTimeMillis();
for (long i = 0; i < 1E10; i++) {
func1("a", "b");
}
long time2 = System.currentTimeMillis();
for (long i = 0; i < 1E10; i++) {
func2(list);
}
System.out.println((time2 - time1) + "/" + (System.currentTimeMillis() - time2));
}
private static void func1(String s1, String s2) { }
private static void func2(List<String> sl) { }
}
However my answer above still stands: if you are calling a function 10 billion times then it might be worth optimising but it is much better practice to start with a focus on clarity and then use profiling to focus code-tuning effort if that is required.
I think you are asking if a List argument is passed by reference. It is. In the compiled machine code, for the list argument just a single pointer to the list object instance will be passed to the function. There is no reason to be concerned about having a large list as an argument.
I recommend only using a List as an argument if the method is interested in the list itself and not only its items, e.g. it plans on modifying it.
For the other cases, if you have a fixed number of arguments, you should have each argument be it's own parameter. But your case suggested that you have a variable number of arguments. For this you could also use varargs:
private void foo(String... strings) {
// `strings` is an array now
}
This has the advantage that the caller can choose to either invoke your function using single objects, or an array:
foo("Hello", "World");
or this
String[] strings = new String[]{"Hello", "World"};
foo(strings);
or even this:
List<String> strings = ...;
foo(strings.toArray(new String[0]));
If you have concerns about turning your list into an array, stick with passing the list itself.
I grok that for capturing lambdas, there needs to be an object allocated (be it Object[] or some abc$Lambda$xyz type). Is it possible to customize this process anyhow? Let's say I have this code:
private void test() {
int x = 5;
Supplier<Integer> supplier = () -> x;
foo(supplier); // potentially passes the supplier to another thread etc.
}
and I don't want to allocate the object capturing x, but instead just get it from a pool and fill in the value; I also know that at some point I can return the object to the pool.
I could write
Supplier<Integer> supplier = pool.get(x, v -> v);
and I could have specialized versions for different argument types (as using Object... would do the allocation (ok, there's a chance that the allocation would be eliminated by escape analysis...) but that would render the code quite unreadable. Therefore I am looking for a more aspect-like way.
Is such thing possible?
EDIT: to make the pool's functionality more obvious, the get could be implemented as
class IntHolderSupplier implements Supplier<Integer> {
int value;
IntFunction<Integer> func;
#Override public Integer get() {
return func.apply(value);
}
}
class Pool {
Supplier<Integer> get(int arg, IntFunction<Integer> func) {
IntHolderSupplier holder = ...;
holder.value = arg;
holder.func = func;
return holder;
}
}
and I would need such holder with specific signatures for all possible types lambdas I want to use.
Maybe I have complicated the example a bit by providing the function - but I wanted to capture the fact that there may be a additional computation applied to the captured argument at time of Supplier.get() invocation.
And please ignore the fact that the int is boxed which can produce an allocation.
To “pool capturing lambdas” is a misnomer. Lambda expressions are a technical solution to get an instance of a functional interface. Since you don’t pool the lambda expressions but the interface instances, dropping every technical aspect of lambda expressions, like immutability or the fact that the JRE/JVM controls their life time, you should name it “pool functional interface instances”.
So you can implement a pool for these instance, just like you can implement a pool for any kind of object. It’s rather unlikely that such a pool performs better than the JVM managed objects created for lambda expressions, but well, you can try it.
It’s simple, if you keep them immutable, thus, don’t try to reuse them for a different value, but only when encountering a previously captured value again. Here is an example for a Supplier cache holding the suppliers for the last 100 encountered values:
class SupplierCache {
static final int SIZE = 100;
static LinkedHashMap<Object,Supplier<Object>> CACHE =
new LinkedHashMap<Object, Supplier<Object>>(SIZE, 1f, true) {
#Override
protected boolean removeEldestEntry(Map.Entry<Object, Supplier<Object>> eldest) {
return size() > SIZE;
}
};
#SuppressWarnings("unchecked")
static <T> Supplier<T> getSupplier(T t) {
return (Supplier<T>)CACHE.computeIfAbsent(t, key -> () -> key);
}
}
(add thread safety, if you need it). So by replacing Supplier<Integer> supplier = () -> x; with Supplier<Integer> supplier = SupplierCache.getSupplier(x); you’ll get the cache functionality and since you don’t have to release them, you don’t have to make error prone assumptions about its life cycle.
Creating a pool of objects implementing Supplier and returning the value of a mutable field, so that you can manually reclaim instances, is not too hard if you simply create an ordinary class implementing Supplier, but well, you open a whole can of worms with manual memory management including the risk of reclaiming an object still being in use. These objects can’t be shared like the immutable object like in the example above. And you replace object allocation with the action of finding a reclaimable pooled instance plus the action of explicitly putting back an instance after use—there’s no reason why this should be faster.
I have an app that is a little bit slow. I thoutght it could be faster using threads.
So, here is my plan: My program have a list of objects of type X and each object X has a very big list of Integers (let's consider Integer for the sake of simplicity).
I have a static method (called getSubsetOfX) that receives a object X from the list of X's and return a list of Integers of the object X the list returned is a subset of all the Integers contained in X.
This method is called for every X contained in the list. Then I insert the returned List in a List of Integer Lists.
This is the code I explained in a compact version:
// Class of object X
public class X{
public List<Integer> listX;
...
}
// Utility class
public class Util{
// Return a sub-set of Integer contained in X
public static List<Integer> getSubsetOfX(X x){...}
}
public class exec{
public static void main(String args[]){
// Let's suppose that lx is already filled with data!
List<X> lx = new ArrayList<X>();
// List of the subsets of integer
List<List<Integer>> li = new ArrayList<ArrayList<Integer>>();
for(X x : lx){
// I want to turn this step "threadrized"
li.add(getSubsetOfX(x));
}
}
}
I don't know if a List allow concurrent insertions. I don't know how to apply threads in it too. I read some about Threads, but, as the run() method doesn't return anything, how can turn the method getSubsetOfX(X x) parallel?
Can you help me doing this?
Just to be clear, getSubsetOfX() is the call that takes a long time, right?
For this sort of task, I'd suggest you look at Java's Executors. The first step would be to create a Callable that runs getSubsetOfX(x) on a given instance of X. Something like this:
public class SubsetCallable implements Callable<List<Integer>> {
X x;
public SubsetCallable(X x) {
this.x = x;
}
public List<Integer> call() {
return Util.getSubsetOfX(x);
}
}
Then you can create an ExecutorService using one of the methods in Executors. Which method to use depends on your available resources and your desired execution model - they're all described in the documentation. Once you create the ExecutorService, just create a SubsetCallable for each instance of X that you have and pass it off to the service to run it. I think it could go something like this:
ExecutorService exec = ...;
List<SubsetCallable> callables = new LinkedList<SubsetCallable>();
for (X x : lx) {
callables.append(new SubsetCallable(x));
}
List<Future<List<Integer>>> futures = exec.invokeAll(lc);
for (Future<List<Integer>> f : futures) {
li.add(f.get());
}
This way you can delegate the intense computation to other threads, but you still only access the list of results in one thread, so you don't have to worry about synchronization. (As winsharp93 pointed out, ArrayList, like most of Java's standard collections, is unsynchronized and thus not safe for concurrent access.)
I don't know if a List allow concurrent insertions.
See Class ArrayList:
Note that this implementation is not
synchronized. If multiple threads
access an ArrayList instance
concurrently, and at least one of the
threads modifies the list
structurally, it must be synchronized
externally. (A structural modification
is any operation that adds or deletes
one or more elements, or explicitly
resizes the backing array; merely
setting the value of an element is not
a structural modification.) This is
typically accomplished by
synchronizing on some object that
naturally encapsulates the list. If no
such object exists, the list should be
"wrapped" using the
Collections.synchronizedList method.
This is best done at creation time, to
prevent accidental unsynchronized
access to the list:
List list = Collections.synchronizedList(new ArrayList(...));
But be careful: Synchronization comes with a significant performance cost. This could relativity the performance you get by using multiple threads (especially when the calculations are quite fast do do).
Thus, avoid accessing those synchronized collections wherever possible. Prefer thread-local lists instead which you can then merge with your shared list using AddAll.
I am trying to fill a RealVector (from Apache Commons Math) with values. I tried using the class's append method, but that didn't actually add anything. So now I'm using a double[], which works fine, except I don't know in advance how big the array needs to be.
private void runAnalysis() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
Double attr;
double[] data = new double[100]; // TODO: bad.
int i = 0;
for (Method m : ParseTree.class.getMethods()) {
if (m.isAnnotationPresent(Analyze.class)) {
attr = (Double) m.invoke(this);
analysis.put(m.getAnnotation(Analyze.class).name(), attr);
data[i++] = attr * m.getAnnotation(Analyze.class).weight();
}
}
weightedAnalysis = new ArrayRealVector(data);
}
How can I deal with this issue? Here are my ideas:
Iterate through the class and count the methods with the annotation, then use that size to initialize the array. However, this will require an extra loop, and reflection is performance-intensive. (right?)
Pick an arbitrary size for the array, doubling it if space runs out. Downside: requires more lines of code
Use a List<Double>, then somehow weasel the Double objects back into doubles so they can be put in the RealVector. Uses more memory for the list.
Just pick a huge size for the starting array, and hope that it never overflows. Downside: this is begging for arrayindexoutofbound errors.
Or am I just using append(double d) wrong?
private void runAnalysis() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
Double attr;
weightedAnalysis = new ArrayRealVector(data);
for (Method m : ParseTree.class.getMethods()) {
if (m.isAnnotationPresent(Analyze.class)) {
attr = (Double) m.invoke(this);
analysis.put(m.getAnnotation(Analyze.class).name(), attr);
weightedAnalysis.append(attr * m.getAnnotation(Analyze.class).weight());
}
}
}
RealVector.append() doesn't modify the vector, but rather constructs a new vector:
The [Java doc of RealVector.append()](http://commons.apache.org/math/apidocs/org/apache/commons/math/linear/RealVector.html#append(double)) explains:
append
RealVector append(double d)
Construct a vector by appending a double to this vector.
Parameters:
d - double to append.
Returns:
a new vector
Please note that using RealVector to construct the vector is quite an expensive operation, as append() would need to copy the elements over and over (i.e. constructing the array in the way you explained runs in O(n^2) time.
I would recommend simply using java's ArrayList<Double> during construction, and then simply converting to RealVector or any other data abstraction you like.
Why not use an ArrayList and add the elements to that?
I would suggest 3 as a good option. Using Double vs double is a minimal problem since autoboxing was introduced.
Using RealVector will take a huge amount of memory and computation time to build, because what you want is:
RealVector newVector = oldVector.append(d);
append() returns a newly constructed object, which is what you'd want for correctness.
If you're okay with heavy overhead on build, take a look at Apache Commons ArrayUtils, specifically add(double) and/or toPrimitive(Double).
You mentioned that you tried the append method, but that didn't actually add anything. After looking at the javadoc, make sure that you assign the result of the append method back to the original value...You probably already tried this, but just in case you overlooked:
RealVector myRealVector = new ArrayRealVector(data);
myRealVector = myRealVector.append(1.0);
in other words, this won't change myRealVector:
RealVector myRealVector = new ArrayRealVector(data);
myRealVector.append(1.0);
you could initialize the array using the
ParseTree.class.getMethods().lenght
as initial capacity:
double[] buf = new double[ ParseTree.class.getMethods().lenght ];
or better
DoubleBuffer buf = DoubleBuffer.allocate([ ParseTree.class.getMethods().lenght);
this may waste some memory but is a safe solution, it depends on how many hit the if inside the loop has.
if you prefer you may count how many methods are annotated in advance and then allocate the exact size for the array