You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by jerome pommier <je...@yahoo.fr.INVALID> on 2017/07/13 07:11:55 UTC

ipojo performance

Hello,
As a scientist, I used to program my calculations in JAVA, and since almost one year I'm doing these using OSGI paradigm, more precisely IPOJO framework. The programs are much more powerful, and I find huge advantages, of course. Anyhow I have questions regarding IPOJO performance. Let me give you an example.
I) STARTING PROBLEM
I have a collection of geometric objects (say Triangle and Square), on which I must do some computations by pairs. Technically I may write something like :

for (Geom g1 : geometricList){
	for (Geom g2 : geometricList){
	compute(g1,g2) ;
	}
}
II) CLARITY
But because the method « compute » should clearly distinct operations when objects are of types Triangle or Square, the code for « compute » method become quickly huge and unreadable (furthermore you can imagine that there is other kinds of geometric objects).
Leading to a much more readable “compute” code, I can partition my objects into geometric categories with the following code :

for (Geom g1 : geometricList){
	for (Geom g2 : TrianglesList){
		computeTriangles(g1,g2) ;
	}
	for (Geom g2 : SquaresList){
		computeSquares(g1,g2) ;
	}
}
III) OSGI SOLUTION
I find that OSGI allows very simple extensions and management of this coding structure when computeTriangles, and computeSquares are designed as OSGI «PairGeometricServices»

for (Geom g1 : geometricList){
	for (Geom g2 : TrianglesList){
		pairGeometricServiceTriangles.compute (g1,g2) ;
	}
	for (Geom g2 : SquaresList){
		pairGeometricServiceSquares.compute(g1,g2) ;
	}
}
« compute » extracts some complicated geometries information on its parameters « g1 », and « g2 », and because within the « g1 » loop, the object g1 stays the same it seems better to write something like :

for (Geom g1 : geometricList){
	pairGeometricServiceTriangles.setFirst(g1) ;
	for (Geom g2 : TrianglesList){
		pairGeometricServiceTriangles.compute (g2) ;
	}
	pairGeometricServiceSquaresInstance.
		reconfigure(pairGeometricServiceTriangles.getDict()) ;
	for (Geom g2 : SquaresList){
		pairGeometricServiceSquares.compute(g2) ;
	}
}
Now « setFirst » computes the geometries information for « g1 » and stores them in some « ServiceProperty » of the associated « PairGeometricService ». The line «reconfigure(...)» allows « pairGeometricSquares » to be updated with these «ServiceProperty» values.
IV) BENCHMARKING
As I said in the beginning, I'm very happy with such OSGI's programming structures which is easily extended and updated. Now, if we look inside the “compute” implementation of the “PairGeometricServiceSquare” we find something like:

…..
@ServiceProperty(name=FIRST_LENGTHS)
double[] first_lengths;
….
public void compute(Geom g2){
...
q=xx*yy*first_lentghs[i]+…;
…
}
….
That is the “ServiceProperty” values are heavily accessed within some loops. Everything is working as expected, but profiling the (very slow) code I found that more than 80% of the total time for the method “compute” comes from reading the “ServiceProperty”, appearing as:
		fqdnClassName._getfirst_lengths
in the profiler.
The trick is to write a line of code at the beginning of “compute”
		double fl[]= first_lengths;
and then to replace “first_length” by “fl” in the code. The extra time has now disappeared.
V) QUESTIONS
Could you let me know:
- Is there any advice about not using “ServiceProperty” fields as any other fields, or is it a implementation artifact ?
- am I doing something wrong with OSGI framework ?

Thank you for your answers, sincerely,

 JP.

Re: ipojo performance

Posted by Jerome Pommier <je...@yahoo.fr>.
Thank you for you answer. However I underline that the extra time observed
when accessing ServiceProperty fields doesn't comes from the profiler (I
used the NetBeans Profiler). Below is a short test :

package felixtest.impl;

import felixtest.services.SimpleService;
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Provides;
import org.apache.felix.ipojo.annotations.ServiceProperty;

@Component
@Provides
public class SimpleImplementation implements SimpleService {

    @ServiceProperty(name = REAL_VALUE)
    double k;
    @ServiceProperty(name = LOOPS_NUMBER)
    int n;
    
    @Override
    public void computeSlow() {
        double res;
        for (int i = 0; i < n; ++i) {
            res = k * i;
        }
    }
    @Override
     public void computeFast() {
        double res,k0=k,n0=n;
        for (int i = 0; i < n; ++i) {
            res = k0 * i;
        }
    }   
}

As you can see the « computeSlow » method reads n and k for each loop. 10E6
loops give me a total run time around 9 secondes, while « computeFast »
accessing only n in the if test is around 3 seconds.
Even worth, when I replaced within that last method n in the if test by n0
the total time is 17 microSeconds !!! 
This of course is not good, and if I must  introduced local variables I will
felt like in the bad old time when creator or methods should hold a long
list of meaningless parameters.
Best regards,

JP



--
View this message in context: http://apache-felix.18485.x6.nabble.com/ipojo-performance-tp5021814p5021879.html
Sent from the Apache Felix - Users mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: ipojo performance

Posted by Clement Escoffier <cl...@gmail.com>.
Hi,

> On 13 Jul 2017, at 09:11, jerome pommier <je...@yahoo.fr.INVALID> wrote:
> 
> Hello,
> As a scientist, I used to program my calculations in JAVA, and since almost one year I'm doing these using OSGI paradigm, more precisely IPOJO framework. The programs are much more powerful, and I find huge advantages, of course. Anyhow I have questions regarding IPOJO performance. Let me give you an example.
> I) STARTING PROBLEM
> I have a collection of geometric objects (say Triangle and Square), on which I must do some computations by pairs. Technically I may write something like :
> 
> for (Geom g1 : geometricList){
> 	for (Geom g2 : geometricList){
> 	compute(g1,g2) ;
> 	}
> }
> II) CLARITY
> But because the method « compute » should clearly distinct operations when objects are of types Triangle or Square, the code for « compute » method become quickly huge and unreadable (furthermore you can imagine that there is other kinds of geometric objects).
> Leading to a much more readable “compute” code, I can partition my objects into geometric categories with the following code :
> 
> for (Geom g1 : geometricList){
> 	for (Geom g2 : TrianglesList){
> 		computeTriangles(g1,g2) ;
> 	}
> 	for (Geom g2 : SquaresList){
> 		computeSquares(g1,g2) ;
> 	}
> }
> III) OSGI SOLUTION
> I find that OSGI allows very simple extensions and management of this coding structure when computeTriangles, and computeSquares are designed as OSGI «PairGeometricServices»
> 
> for (Geom g1 : geometricList){
> 	for (Geom g2 : TrianglesList){
> 		pairGeometricServiceTriangles.compute (g1,g2) ;
> 	}
> 	for (Geom g2 : SquaresList){
> 		pairGeometricServiceSquares.compute(g1,g2) ;
> 	}
> }
> « compute » extracts some complicated geometries information on its parameters « g1 », and « g2 », and because within the « g1 » loop, the object g1 stays the same it seems better to write something like :
> 
> for (Geom g1 : geometricList){
> 	pairGeometricServiceTriangles.setFirst(g1) ;
> 	for (Geom g2 : TrianglesList){
> 		pairGeometricServiceTriangles.compute (g2) ;
> 	}
> 	pairGeometricServiceSquaresInstance.
> 		reconfigure(pairGeometricServiceTriangles.getDict()) ;
> 	for (Geom g2 : SquaresList){
> 		pairGeometricServiceSquares.compute(g2) ;
> 	}
> }
> Now « setFirst » computes the geometries information for « g1 » and stores them in some « ServiceProperty » of the associated « PairGeometricService ». The line «reconfigure(...)» allows « pairGeometricSquares » to be updated with these «ServiceProperty» values.
> IV) BENCHMARKING
> As I said in the beginning, I'm very happy with such OSGI's programming structures which is easily extended and updated. Now, if we look inside the “compute” implementation of the “PairGeometricServiceSquare” we find something like:
> 
> …..
> @ServiceProperty(name=FIRST_LENGTHS)
> double[] first_lengths;
> ….
> public void compute(Geom g2){
> ...
> q=xx*yy*first_lentghs[i]+…;
> …
> }
> ….
> That is the “ServiceProperty” values are heavily accessed within some loops. Everything is working as expected, but profiling the (very slow) code I found that more than 80% of the total time for the method “compute” comes from reading the “ServiceProperty”, appearing as:
> 		fqdnClassName._getfirst_lengths
> in the profiler.
> The trick is to write a line of code at the beginning of “compute”
> 		double fl[]= first_lengths;
> and then to replace “first_length” by “fl” in the code. The extra time has now disappeared.
> V) QUESTIONS
> Could you let me know:
> - Is there any advice about not using “ServiceProperty” fields as any other fields, or is it a implementation artifact ?

iPOJO instruments all fields to intercept reads / writes. If interception time is too expensive for you, you have found the solution by copying the value into a local variable. However, the interception methods have been designed to be inlined by the JIT meaning that the cost should be meaningless in most of the cases. When you use a profiler, I’m not sure the JIT can apply all the optimizations.

Clement

> - am I doing something wrong with OSGI framework ?
> 
> Thank you for your answers, sincerely,
> 
> JP.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org