Hello, Lubomir!

The business problem was: Here is vector of vectors, where each subvector 
contains (initially sequential) unique numbers. Then a set of threads are 
started that repeatedly select two random positions in two random 
subvectors and swap them, in a transaction. After N iterations, we should 
see no values get lost or duplicated in the shuffle.

Both realizations are correct. But, Java version was faster from 10 to 20 
times. And I decided to investigate why? Changing the locking level from 
vector to individual number I didn't change the business problem criteria 
(initial conditions). But now Clojure works with comparable speed with 
Java. And both are acceptable for business (correctness guaranteed).

For business it is not important what type of locks we are using. But time 
& money are important. Slow speed from 10 to 20 times it is matters.

My goal is achieved: Clojure code was smaller in 10 times than Java code. 
~150 LOC in java vs 15 LOC in Clojure. And now I demonstrated to Java 
developers that Clojure code is fast enough. But Clojure code is totally 
simple. If business goals would be changed it is not so easy in Java to put 
right locks to the right places for new contions. So here is business 
values for Clojure: 
- dead simple logic;
- reduced T2M;
- less code less bugs;
- fast enough.

(Sold to business.)

Mike.

среда, 18 октября 2017 г., 20:33:28 UTC+3 пользователь Lubomir Konstantinov 
написал:
>
> Among other things (you are trying to compare two totally different 
> synchronization mechanisms) - cause its doing something else :)
>
> The version from the example is preserving the atomicity of the whole 
> vector. Your version is working on an element level.
>
> In the former, If multiple threads are trying to update same v1 or v2 
> simultaneously - STM will retry the transaction. In the latter, the 
> collision needs to be on the same cells as well.
>
> On Wednesday, 18 October 2017 11:01:20 UTC+3, Mike wrote:
>>
>> Hi, Deniel.
>>
>> I made minor change from example (https://clojure.org/reference/refs) 
>> and now Clojure code works at speed 60-80% of pure Java code.
>> I changed level of lock (refs). In example of clojure org level of refs 
>> is higher and that is why code works slower, i.e  [ (ref[ 0 1 2..]) (ref 
>> [..]) .. ]
>> I made [ [(ref 0) (ref 1) ...] [ ref ...] ...] and now it is flying.
>>
>> Here is the code:
>>
>> (defn run [nvecs nitems nthreads niters]
>>   (let [vec-refs (vec (map vec (partition nitems (map ref (range (* nvecs 
>> nitems))))))
>>         swap #(let [v1 (rand-int nvecs)
>>                     v2 (rand-int nvecs)
>>                     i1 (rand-int nitems)
>>                     i2 (rand-int nitems)]
>>                 (dosync
>>                  (let [temp @(nth (vec-refs v1) i1)]
>>                    (ref-set (nth (vec-refs v1) i1)  @(nth (vec-refs v2) 
>> i2))
>>                    (ref-set (nth (vec-refs v2) i2) temp))))
>>         report #(do 
>>                   (println "Distinct:"
>>                            (count (distinct (map deref (apply concat 
>> vec-refs))))))]    
>>     (dorun (apply pcalls (repeat nthreads #(dotimes [_ niters] (swap)))))
>>     (report)))
>>
>> вторник, 17 октября 2017 г., 0:19:26 UTC+3 пользователь Daniel Compton 
>> написал:
>>>
>>> Hi Mike
>>>
>>> A few thoughts
>>>
>>> * In my experience it is not unusual that idiomatic Clojure could be 10x 
>>> slower than the equivalent Java.
>>> * Where did you do your timing on the ref calculation? In the Clojure 
>>> version it calculates distinct at the end.
>>> * How did you do your benchmarking? JVM benchmarking is very tricky, and 
>>> could easily overwhelm all other results.
>>> * Have you verified that your Java code is correct under all situations?
>>>
>>> Overall I think this is a good illustration of a tradeoff that Clojure 
>>> makes against Java. Idiomatic Clojure code is often slower than the Java 
>>> that one might write. However (to my eyes) it is far easier to read, 
>>> understand, and crucially to verify correctness even on the small example 
>>> of swapping numbers. Most of the time, for most systems this is a good 
>>> tradeoff. Ensuring correctness and performance with locks in a larger 
>>> concurrent system becomes even more difficult. 
>>>
>>> However if performance is critical, and you have the time and skill to 
>>> verify that your locking algorithm is correct, then you can always use 
>>> locks. Either through direct calls to Java interop, or writing your locking 
>>> code in Java and calling that via Java interop.
>>>
>>> For more info on this, you can read the conversation between Rich 
>>> Hickey and Cliff Click about STMs vs Locks 
>>> <http://web.archive.org/web/20100405125722/http://blogs.azulsystems.com/cliff/2008/05/clojure-stms-vs.html>
>>> .
>>>
>>> --
>>> Daniel.
>>>
>>> On Mon, Oct 16, 2017 at 7:44 PM Mike <145...@gmail.com> wrote:
>>>
>>>> https://clojure.org/reference/refs correct link
>>>>
>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>

-- 
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.

Reply via email to