For anybody interested, I manage to improve performance up to ~2x slower 
than standard hash-map and pushed it to clojars.

https://github.com/frankiesardo/linked

linked-set is still a bit slow so I'll keep investigating on it.

On Tuesday, April 15, 2014 2:31:14 PM UTC+2, Frankie Sardo wrote:
>
> Thanks for the pointers Andy.
> I had a look at the ordered-map and indeed is a smart and fast 
> implementation. However it relies on continuously growing a backing array, 
> filling dissoc-iated values with nil and hoping that at one point the user 
> will call (compact map) to free all the unused positions. In theory my 
> implementation should scale better as it only uses the space that it needs.
>
> However after more benchmarking I observed the following:
>
> - (assoc with multiple key-vals) does indeed slow down the operations. But 
> calling transient and persistent! only makes things worse with bigger maps 
> (I guess the whole map is copied before making it transient).
> - There is quite a bottleneck due to querying 'head' and 'tail' on every 
> insertion. I thought the performance of a standard hash-map was definitely 
> better :)
>
> I could speed up the assoc performance avoiding the insertion of head and 
> tail inside the delegate-map and keeping those two nodes as class fields. 
> That won't make dissoc better but it seems like a reasonable compromise.
>
> Out of curiosity, is anybody using ordered-map in their projects? Since 
> performance is comparable to a standard hash-map I would always prefer to 
> use it for the deterministic ordering of the keys. Makes reproducing and 
> catching bugs/errors easier imho.
>
>
> On Monday, April 14, 2014 10:48:48 PM UTC+2, Andy Fingerhut wrote:
>>
>> You may also want to take a look at the 'ordered' library, intended to 
>> achieve a similar affect as you describe of remembering elements in the 
>> order they were inserted.  I don't know which of the two Github repos below 
>> is the current latest one, but it should be one of them:
>>
>>     https://github.com/flatland/ordered
>>     https://github.com/amalloy/ordered
>>
>> Andy
>>
>>
>> On Mon, Apr 14, 2014 at 12:36 PM, Andy Fingerhut <andy.fi...@gmail.com>wrote:
>>
>>> I don't have time right now to look at the details of your 
>>> implementation, but can answer at least one of your questions.
>>>
>>> Clojure's normal PersistentHashMap data structure does create a new 
>>> object for every key you remove (with dissoc), add, or modify the value for 
>>> (with assoc).  So if a single assoc call is made that adds/changes the 
>>> values for 5 keys, 5 new PersistentHashMap objects will be created.
>>>
>>> That can be avoided if you call transient first, then assoc! N times 
>>> (each time on the result returned by the previous assoc!), then 
>>> persistent.  There the assoc! calls still can create new objects, but they 
>>> will often simply edit the existing transient data structure in place.  
>>> These are a bit trickier to implement, so if I were you I would focus on 
>>> getting the persistent version correct and as fast as you can before 
>>> worrying about a transient version.  Either that, or do not even both 
>>> creating a transient version at all.
>>>
>>> Andy
>>>
>>>
>>> On Mon, Apr 14, 2014 at 11:59 AM, Frankie Sardo <fran....@gmail.com>wrote:
>>>
>>>> I'm on a mission to implement an ordered map and set structure for 
>>>> Clojure. Much like LinkedHashMap for Java but as a persistent data 
>>>> structure.
>>>> The idea is that instead of saving a simple [k v] MapEntry we can save 
>>>> [k v left-node-key right-node-key] plus a global head-node-key to walk 
>>>> through the chains of nodes.
>>>> Adding a new element creates a new node with a reference on the current 
>>>> tail and the head node and updates the tail and head node to reference the 
>>>> new key in the middle.
>>>> Removing an element dissociates the selected node and associates the 
>>>> newly updated nodes at the left and the right of the removed one.
>>>>
>>>> What puzzles me is the overall performance of this data structure. 
>>>> While Big-O complexity is the same I knew it would be slower due to extra 
>>>> accesses to the inner map, but I expected to be close  to the performance 
>>>> of a normal hash-map. Instead insertion is about 5x slower while the 
>>>> removal is 2x slower. So I wonder: is assoc-ing multiple keys at a time 
>>>> generating multiple persistent maps? Or am I doing something blatantly 
>>>> wrong here?
>>>>
>>>> However, if somebody'd like to have a look at it I pushed an initial 
>>>> version here https://github.com/frankiesardo/linked. Any help is much 
>>>> appreciated as I'm still a Clojure newbie.
>>>>  
>>>> -- 
>>>> 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