classpath-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [cp-patches] FYI: Implemented an ObjectPool


From: Robert Schuster
Subject: Re: [cp-patches] FYI: Implemented an ObjectPool
Date: Sat, 02 Jul 2005 00:27:23 +0200
User-agent: Mozilla/5.0 (X11; U; Linux i686; de-AT; rv:1.7.8) Gecko/20050514

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Ok,
I have seen this class was removed now.

So forget about this mail :)

cu
Robert

Robert Schuster wrote:
> Hi,
> shouldn't the pooling class use a WeakHashMap?
> 
> And then I want to admit that the Apidoc should really explain when to
> use a pooled object and when it is not good to use it. Eg. for all kind
> of MouseEvent I think it is not a good idea to use the pool because the
> user can access the Point instance and store it somewhere.
> 
> Putting such an object back in the pool (even if it was untouched in
> Classpath API code) would sooner or later cause havoc (when the values
> in the object are overwritten and the user did not expect that).
> 
> And now an example to get to know whether I have understood how to use
> the object pool correctly:
> In JTable I would change all instantiations of Point to
> ObjectPool.getPoint(). When new values for these internal objects are
> available I set them with begin.x, begin.y and so on.
> 
> When the JTable instance is freed (finalize) I return the Point
> instances to the ObjectPool.
> 
> Done right?
> 
> cu
> Robert
> 
> Roman Kennke wrote:
> 
>>>Hi,
>>>
>>>
>>>
>>>>>I implemented and added an ObjectPool class.
>>>>
>>>>Please measure! Don't assume that this will lead to better performance.
>>>>I do follow your reasoning. But ultimately this is the job of the
>>>>allocator/garbage collector.
>>>
>>>
>>>I completely agree with you that ideally this should be done in the GC.
>>>This is why I hestitate to actually introduce some 'optimizations'. I
>>>don't know about the current situation in free VMs Garbage Collectors
>>>and how the impact would be. It would be helpful if some VM hackers
>>>could comment on the issue.
>>>
>>>
>>>
>>>>Please make it really easy to turn on/off caching so people can do real
>>>>measurements of the performance impact.
>>>
>>>
>>>I have added a flag in the ObjectPool that can turn off the cache. As
>>>well as some counters that count how many objects are
>>>requested/returned/created/pooled. This is not a very clever benchmark,
>>>since it does not actually measure performance (time-wise).
>>>
>>>
>>>
>>>>And only introduce it when it is
>>>>a clear win.
>>>
>>>
>>>Seeing that it is quite difficult to find the right spots where objects
>>>should actually be returned into the pool, I strongly hesitate now to
>>>introduce anything.
>>>
>>>
>>>
>>>>What seems to happen a lot in larger projects is that someone introduces
>>>>some pooling/caching of certain constructs and when some implementation
>>>>detail somewhere else in the stack changes the pooling/caching isn't
>>>>revised/remeasured to see if it still makes sense (or that it actually
>>>>decreases performance given the new circumstances!).
>>>>Don't let that happen in this case.
>>>
>>>
>>>I won't. It would be nice if some folks would play a little and comment
>>>on this issue. Note that the pool isn't actually in use in Classpath, it
>>>only sits around now for testing. I committed the following changes that
>>>could help benchmarking:
>>>
>>>2005-07-01  Roman Kennke  <address@hidden>
>>>
>>>        * gnu/classpath/ObjectPool.java:
>>>        Introduced flag for turning on/off caching.
>>>        (getInstance): Synchronized access to this method.
>>>        (borrowObject): Synchronized access to the pool.
>>>        Added some benchmarking statements.
>>>        (returnObject): Synchronized access to the pool.
>>>        Added some benchmarking statements.
>>>        (createObject): Synchronized access to the pool.
>>>        Added some benchmarking statements.
>>>        (printStats): New method. Prints out some stats about the pool
>>>     usage.
>>>
>>>/Roman
>>>
>>>
>>>
>>>------------------------------------------------------------------------
>>>
>>>Index: gnu/classpath/ObjectPool.java
>>>===================================================================
>>>RCS file: /cvsroot/classpath/classpath/gnu/classpath/ObjectPool.java,v
>>>retrieving revision 1.2
>>>diff -u -r1.2 ObjectPool.java
>>>--- gnu/classpath/ObjectPool.java    1 Jul 2005 10:58:07 -0000       1.2
>>>+++ gnu/classpath/ObjectPool.java    1 Jul 2005 13:04:39 -0000
>>>@@ -77,6 +77,12 @@
>>> public final class ObjectPool
>>> {
>>> 
>>>+  /** The maximum number of instances that we keep for each type. */
>>>+  private static final int MAX_POOL_SIZE = 128;
>>>+
>>>+  /** This flag turns on/off caching (for benchmarking purposes). */
>>>+  private static final boolean IS_CACHING = true;
>>>+
>>>   /** The only instance of ObjectPool. */
>>>   private static ObjectPool instance;
>>> 
>>>@@ -87,6 +93,14 @@
>>>    * requested type is in the pool.
>>>    */
>>>   private HashMap pool;
>>>+  
>>>+  /**
>>>+   * Collect some stats in this fields. TODO: Can be removed later.
>>>+   */
>>>+  int created = 0;
>>>+  int requested = 0;
>>>+  int returned = 0;
>>>+  int pooled = 0;
>>> 
>>>   /**
>>>    * Creates a new instance of ObjectPool. This constructor is made private
>>>@@ -102,7 +116,7 @@
>>>    *
>>>    * @return an ObjectPool instance ready for use
>>>    */
>>>-  public static ObjectPool getInstance()
>>>+  public static synchronized ObjectPool getInstance()
>>>   {
>>>     if (instance == null)
>>>       instance = new ObjectPool();
>>>@@ -123,15 +137,32 @@
>>>    */
>>>   public Object borrowObject(Class type)
>>>   {
>>>+    // This is only here for benchmarking purposes.
>>>+    if (!IS_CACHING)
>>>+      return createObject(type);
>>>+    // Counts the requested objects. This is only here for benchmarking
>>>+    // purposes.
>>>+    requested++;
>>>+    if (requested % 10000 == 0)
>>>+      printStats();
>>>+
>>>+
>>>     Object object = null;
>>>-    Stack pooledInstances = (Stack) pool.get(type);
>>>+    Stack pooledInstances = null;
>>>+    synchronized (this)
>>>+      {
>>>+    pooledInstances = (Stack) pool.get(type);
>>>+      }
>>>     if (pooledInstances == null)
>>>       object = createObject(type);
>>>     else
>>>       if (pooledInstances.size() == 0)
>>>     object = createObject(type);
>>>       else
>>>-    object = pooledInstances.pop();
>>>+    synchronized (this)
>>>+      {
>>>+        object = pooledInstances.pop();
>>>+      }
>>>     return object;
>>>   }
>>> 
>>>@@ -142,14 +173,36 @@
>>>    */
>>>   public void returnObject(Object object)
>>>   {
>>>+    // This is only here for benchmarking purposes.
>>>+    if (!IS_CACHING)
>>>+      return;
>>>+    // Count the returned objects. This is only here for benchmarking 
>>>purposes.
>>>+    returned++;
>>>+
>>>     Class type = object.getClass();
>>>-    Stack pooledInstances = (Stack) pool.get(type);
>>>+    Stack pooledInstances = null;
>>>+    synchronized (this)
>>>+      {
>>>+    pooledInstances = (Stack) pool.get(type);
>>>+      }
>>>     if (pooledInstances == null)
>>>       {
>>>     pooledInstances = new Stack();
>>>-    pool.put(type, pooledInstances);
>>>       }
>>>-    pooledInstances.push(object);
>>>+    if (pooledInstances.size() < MAX_POOL_SIZE)
>>>+      synchronized (this)
>>>+    {
>>>+      pool.put(type, pooledInstances);
>>>+
>>>+      // Count the objects that are actually pooled. This is only
>>>+      // here for benchmarking purposes.
>>>+      pooled++;
>>>+    }
>>>+
>>>+    synchronized (this)
>>>+      {
>>>+    pooledInstances.push(object);
>>>+      }
>>>   }
>>> 
>>>   /**
>>>@@ -162,6 +215,11 @@
>>>    */
>>>   private Object createObject(Class type)
>>>   {
>>>+    // Counts the objects that are created here. This is only here for
>>>+    // benchmarking purposes.
>>>+    created++;
>>>+
>>>+
>>>     Object object = null;
>>>     try
>>>       {
>>>@@ -177,4 +235,16 @@
>>>       }
>>>     return object;
>>>   }
>>>+
>>>+  /**
>>>+   * This method prints out some stats about the object pool. This gives
>>>+   * an indication on how efficiently the pool is used.
>>>+   */
>>>+  void printStats()
>>>+  {
>>>+    System.err.println("Requested Objects: " + requested);
>>>+    System.err.println("Returned Objects: " + returned);
>>>+    System.err.println("Created Objects: " + created);
>>>+    System.err.println("Pooled Objects: " + pooled);
>>>+  }
>>> }
>>>
>>>
>>>------------------------------------------------------------------------
>>>
>>>_______________________________________________
>>>Classpath-patches mailing list
>>>address@hidden
>>>http://lists.gnu.org/mailman/listinfo/classpath-patches
> 

_______________________________________________
Classpath-patches mailing list
address@hidden
http://lists.gnu.org/mailman/listinfo/classpath-patches


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFCxcNKG9cfwmwwEtoRAuO8AJ9QwLDpMqHVQXInSujOd2Id6aHofwCeLHTr
UQXNdVn/4U0J+Afs2PGpcIE=
=t70q
-----END PGP SIGNATURE-----




reply via email to

[Prev in Thread] Current Thread [Next in Thread]