[concurrency-interest] ConcurrentLinkedBlockingQueue vs LinkedBlockingQueue

Szabolcs Ferenczi szabolcs.ferenczi at gmail.com
Tue Apr 3 15:33:17 EDT 2007


Hi Hanson,

Here are the results on my dual core XP Home when the -server switch
is specified:

CLBQ  669+666+673+301+300+299+309+309+584+575=4685
LBQ   790+784+630+564+583+551+550+848+691+806=6797
0.69

WITH BUSY LOOP
CLBQ  657+666+677+632+651+649+649+654+662+647=6544
LBQ   942+846+842+810+825+948+943+949+942+981=9028
0.72

WITH SEMAPHORE UNFAIR
CLBQ  1184+1225+1188+1199+1197+1205+1210+1207+1188+1186=11989
LBQ   813+820+896+929+932+943+922+967+909+902=9033
1.33

WITH SEMAPHORE FAIR
CLBQ  1034+1051+1031+1107+1105+1110+946+1044+1086+1058=10572
LBQ   847+988+1039+933+1017+580+842+860+790+818=8714
1.21

WITH CONDITIONAL VARIABLE
CLBQ  1053+1006+1064+1023+1002+1041+1012+1030+1013+1023=10267
LBQ   880+932+1061+1044+1049+1066+1107+1052+1054+1056=10301
0.996

I hope this helps.

Best Regards,
Szabolcs

On 03/04/07, Hanson Char <hanson.char at gmail.com> wrote:
> Thanks Szablocs.  Would you mind running it once more with the
> "-server" switch on ?
>
> java -server -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode
> -XX:+DisableExplicitGC -jar q-test.jar
>
> Hanson
>
> On 4/2/07, Szabolcs Ferenczi <szabolcs.ferenczi at gmail.com> wrote:
> > On 02/04/07, Hanson Char <hanson.char at gmail.com> wrote:
> >
> > > Based on a recent test on Windows XP Professional with 1 CPU,
> > > ConcurrentLinkedBlockingQueue performs 83% faster than
> > > LinkedBlockingQueue.  Unfortunately I don't have access to a more
> > > powerful box (with multi-processors) to do more testings.
> >
> > Hi Hanson,
> >
> > I have run your performance test on a dual core XP version. Here is
> > the summary of the averages:
> >
> > CLBQ  748+791+752+743+743+730+732+752+737+705=7433
> > LBQ   1271+1230+1258+1258+1221+1201+1194+1178+1206+1206=12223
> > LBQ/CLBQ = 0.61
> >
> > However, as I have indicated earlier, your CLBQ offer/take combination
> > implements a busy waiting loop with some optimalization. With a simple
> > busy waiting loop the figures are like this:
> >
> > CLBQ  776+688+739+688+702+684+675+715+708+715=7090
> > LBQ   1243+1243+1197+1207+1265+1265+1259+1256+1253+1261=12449
> > LBQ/CLBQ = 0.57
> >
> >     public boolean offer(E e) {
> >         return q.offer(e);
> >     }
> >     public E take() throws InterruptedException
> >     {
> >         for (;;) {
> >             E e = q.poll();
> >
> >             if (e != null)
> >                 return e;
> >             if (Thread.interrupted())
> >             {
> >                 throw new InterruptedException();
> >             }
> >         }
> >     }
> >
> > I have also checked a variant with the standard conditional variable:
> >
> > CLBQ  3072+2437+1967+1918+2828+1925+1930+1904+1882+1933=21796
> > LBQ   1261+1298+1196+1215+1212+1182+1185+1210+1198+1197=12154
> > LBQ/CLBQ = 1.79
> >
> >     public boolean offer(E e) {
> >         boolean b;
> >         synchronized(takeLock) {
> >             b = q.offer(e);
> >             takeLock.notify();
> >         }
> >         return b;
> >     }
> >     public E take() throws InterruptedException
> >     {
> >         E e;
> >         synchronized(takeLock) {
> >             while (q.isEmpty()) {
> >                 takeLock.wait();
> >             }
> >             e = q.poll();
> >         }
> >         return e;
> >     }
> >
> > Finally, I have checked the same performance test with semaphore
> > scheduling:
> >
> > With fair semaphore:
> > CLBQ  3248+2637+2676+2690+2024+2197+2181+2134+2142+2139=24068
> > LBQ   1185+1256+1169+1201+1210+1159+1151+1162+1170+1172=11835
> > LBQ/CLBQ = 2.03
> >
> > With unfair semaphore:
> > CLBQ  2473+2133+2249+2267+2226+2277+2155+2244+2284+2269=22577
> > LBQ   1238+1222+1200+1176+1183+1183+1293+1207+1201+1186=12089
> > LBQ/CLBQ = 1.87
> >
> >     private final Semaphore availableItems = new Semaphore(0, true);
> >     public synchronized boolean offer(E e) {
> >         boolean b = q.offer(e);
> >         availableItems.release();
> >         return b;
> >     }
> >     public E take() throws InterruptedException
> >     {
> >         availableItems.acquire();
> >         synchronized(this) {
> >             E e = q.poll();
> >             return e;
> >         }
> >     }
> >
> > My final note is that the N producer 1 consumer performance test is
> > not a good choice in this case. The reason is that you have added
> > some synchronization (lock free one) to schedule the consumers. On the
> > other hand the performance test omits consumer scheduling since the
> > N consumers make sure that the consumer should not be scheduled at the take
> > method since there will always be some items in the queue for the consumer.
> >
> > Best Regards,
> > Szabolcs
> >
>


More information about the Concurrency-interest mailing list