Hello! 

I took an example from https://clojure.org/references/refs (select two 
random positions in two random vectors and swap them, in a transaction.)
A java version is faster in 10 times (in attach), and threre is no human 
brain complexity in concurrency in  java version.

Why clojure version so slow?

Mike.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
package org.mypack;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by sbt-starovoytov-av on 27.03.2017.
 */
public class MainClass {

    private static int ARRAY_COUNT = 10;
    private static int ARRAY_SIZE = 100;
    private static int THREAD_COUNT = 100;
    private static long JOB_TIME = 1_000L;
    private static int REPLACE_COUNT = 1_000_000;

    private final static AtomicInteger count = new AtomicInteger(0);

    public static MyLong[][] table;

    private static void fill() {

        table = new MyLong[ARRAY_COUNT][ARRAY_SIZE];

        for (int i = 0; i < ARRAY_COUNT; i++)
            for (int j = 0; j < ARRAY_SIZE; j++)
                table[i][j] = new MyLong(j * ARRAY_COUNT + i);
    }

    public static void main(String[] args) {

        long l = System.currentTimeMillis();

        if (args.length >= 1)
            ARRAY_COUNT = Integer.parseInt(args[0]);

        if (args.length >= 2)
            ARRAY_SIZE = Integer.parseInt(args[1]);

        if (args.length >= 3)
            THREAD_COUNT = Integer.parseInt(args[2]);

        if (args.length >= 4)
            REPLACE_COUNT = Integer.parseInt(args[3]);

        fill();

        //long sum = checkSum();

        Thread[] threads = new Thread[THREAD_COUNT];

        for (int i = 0; i < threads.length; i++) {
            threads[i] = new MyThread();
            threads[i].start();
        }

        /*try {
            Thread.currentThread().sleep(JOB_TIME);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        for (int i = 0; i < threads.length; i++) {
            threads[i].interrupt();
        }*/

        for (int i = 0; i < threads.length; i++) {
            try {
                threads[i].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        l = System.currentTimeMillis() - l;
        System.out.println(l);
    }

    private static long checkSum() {

        long sum = 0;

        for (int i = 0; i < ARRAY_COUNT; i++)
            for (int j = 0; j < ARRAY_SIZE; j++)
                sum += table[i][j].getValue();

        return sum;
    }

    private static class MyThread extends Thread {

        @Override
        public void run() {

            //Random r = new Random(Thread.currentThread().getId());
            long c;

            int i = 0;

            int i1 = new Random().nextInt(ARRAY_COUNT);
            int j1 = new Random().nextInt(ARRAY_SIZE);
            int i2 = new Random().nextInt(ARRAY_COUNT);
            int j2 = new Random().nextInt(ARRAY_SIZE);

            while (true) {


                if (table[i1][j1].lock()) {
                    if (table[i2][j2].lock()) {

                        c = table[i1][j1].getValue();

                        table[i1][j1].setValue(table[i2][j2].getValue());
                        table[i1][j1].unLock();
                        table[i2][j2].setValue(c);
                        table[i2][j2].unLock();

                        /*if (isInterrupted()) {
                            return;
                        }*/

                        i++;

                        if (i >= REPLACE_COUNT)
                            return;

                        i1 = new Random(Thread.currentThread().getId()).nextInt(ARRAY_COUNT);
                        j1 = new Random(Thread.currentThread().getId()).nextInt(ARRAY_SIZE);
                        i2 = new Random(Thread.currentThread().getId()).nextInt(ARRAY_COUNT);
                        j2 = new Random(Thread.currentThread().getId()).nextInt(ARRAY_SIZE);

                        continue;

                    } else {
                        table[i1][j1].unLock();
                    }
                }
                //count.incrementAndGet();
                yield();
            }
        }

    }

    private static class MyLong {

        private Long value;
        private Lock lock = new ReentrantLock();

        public MyLong(long value) {
            this.value = value;
        }

        public boolean lock() {
            return lock.tryLock();
        }

        public void unLock() {
            lock.unlock();
        }

        public long getValue() {
            return value;
        }

        public void setValue(long value) {
            this.value = value;
        }
    }
}

Reply via email to