Thanks for your comments. Let me try to provide you with a little more information.
On Thu, Jan 8, 2009 at 4:38 AM, Ian Eslick <esl...@media.mit.edu> wrote: > > On Jan 8, 2009, at 3:22 AM, Elliott Slaughter wrote: > > > Another issue is that the cache-style declaration in persistent > > classes doesn't get inherited by default. This particularly annoying > > since this throws an error merely by inheriting cached slots from a > > superclass. > > Hmmmm...it should inherit by default unless you are overriding the > base class slot. I'll look into this too. It looks like cache-style is inherited when no new cached slots are declared. But when new cached slots are declared, it produces a rather strange error. I have attached a test case for you to examine. > That said, I could probably avoid reading indexed slots if I used > > the query language discussed on another thread. (Currently I use get- > > instances-by-value to cons a list of objects, and then sort by the > > indexed slot to effectively iterate over two sorted slots.) > > The query system would basically do this: > > (let ((a (map-inverted-index #'identity 'slot1 :collect t :oids t)) > (b (map-inverted-index #'identity 'slot2 :collect t :oids t))) > (mapcar #'elephant::controller-recreate-instance > (merge-unique (sort a #'<) (sort b #'<)) What I need to do is more like (let ((list (map-inverted-index #'identity 'slot1 :value foo :collect t))) (sort list #'< :key #'slot2)) which is effectively what I am currently doing with get-instances-by-value. Is there a better way to efficiently iterate over one value in the first slot, with the ordering of the second slot? (Should I look into creating another level of btree for holding each subset of object in order?) You can also do map-inverted-index and accumulate only values matching > the second value as discussed earlier using an accumulation closure as > an argument. For small sets on the first slot, this is probably > faster. In general mapping is always more efficient than get- > instances... Most of the time, the sets will be close in size. Less frequently, the second set will be much larger. > I get roughly the same results as you on the micro-benchmarks. When > > using checkout caching in the game, I get about a 2x speed increase. > > It is still about 3x slower than no database. > > It would be interesting to see some profile data on this to see what, > if anything, in BDB/Elephant could be improved. Do you want profile results from my package, or from Elephant internals? Either way, I have attached to profile reports. I hope you find them helpful. On Thu, Jan 8, 2009 at 5:02 AM, Ian Eslick <esl...@media.mit.edu> wrote: > By the way, a write through mode is complex because if a transaction > is rolled back your index could differ from your memory state so you > would then have to keep track if slot writes to undo them on rollback... I don't currently (or expect to) rollback changes, so this isn't an issue with my particular application. Are you caching blocks of objects for short term operations or long > term ones? > I would like to cache all objects in the current room, so the only major context switches should be when the player moves between rooms. So long term. -- Elliott Slaughter "Any road followed precisely to its end leads precisely nowhere." - Frank Herbert
;;; rm -rf test.db && sbcl --load class_cache-style_inheritence_bug.lisp (asdf:oos 'asdf:load-op :elephant) (use-package :ele) (ensure-directories-exist "test.db/") (open-store '(:bdb "test.db/")) (defpclass foo () ((a :initarg :a :cached t)) (:cache-style :checkout)) (defpclass bar (foo) ((b :initarg :b :cached t)) ;; To fix the following code, change #+ to #- #+omit (:cache-style :checkout)) (defvar *bar* (make-instance 'bar :a 5))
seconds | consed | calls | sec/call | name ---------------------------------------------------------- 0.476 | 11,291,472 | 66,102 | 0.000007 | ELEPHANT:CURSOR-NEXT 0.405 | 437,096 | 66,966 | 0.000006 | ELEPHANT:FIND-INVERTED-INDEX 0.370 | 266,200 | 66,868 | 0.000006 | ELEPHANT:CURSOR-SET 0.306 | 8,287,600 | 66,975 | 0.000005 | ELEPHANT:MAKE-CURSOR 0.162 | 1,216,552 | 33,858 | 0.000005 | ELEPHANT:TRANSLATE-AND-INTERN-S YMBOL 0.158 | 13,668,968 | 66,868 | 0.000002 | ELEPHANT:MAP-BTREE 0.109 | 6,448,184 | 1 | 0.108992 | ELEPHANT:OPEN-STORE 0.091 | 0 | 66,975 | 0.000001 | ELEPHANT:CURSOR-CLOSE 0.032 | 1,763,752 | 2 | 0.015997 | ELEPHANT:ADD-INDEX 0.016 | 127,936 | 101 | 0.000158 | ELEPHANT:PERSISTENT-CHECKOUT 0.015 | 184,304 | 2,592 | 0.000006 | ELEPHANT:GET-VALUE 0.015 | 8,192 | 105 | 0.000143 | ELEPHANT:CURSOR-GET-BOTH 0.010 | 0 | 66,409 | 0.0000002 | ELEPHANT:CURSOR-INITIALIZED-P 0.000 | 511,504 | 5 | 0.000000 | ELEPHANT:MAKE-DUP-BTREE 0.000 | 12,328 | 2 | 0.000000 | ELEPHANT:MAP-CLASS 0.000 | 0 | 2 | 0.000000 | ELEPHANT:CURSOR-PSET 0.000 | 0 | 1 | 0.000000 | ELEPHANT:FLUSH-INSTANCE-CACHE 0.000 | 8,192 | 101 | 0.000000 | ELEPHANT:PERSISTENT-CHECKIN 0.000 | 1,699,320 | 66,862 | 0.000000 | ELEPHANT:MAP-INVERTED-INDEX 0.000 | 8,192 | 208 | 0.000000 | GET-INSTANCE-BY-VALUE 0.000 | 57,328 | 64 | 0.000000 | ELEPHANT:STRUCT-CONSTRUCTOR 0.000 | 0 | 105 | 0.000000 | ELEPHANT:REMOVE-KV-PAIR 0.000 | 0 | 216 | 0.000000 | ELEPHANT:KEY-FN 0.000 | 8,192 | 214 | 0.000000 | ELEPHANT:REMOVE-KV 0.000 | 0 | 133,724 | 0.000000 | GET-INSTANCES-BY-VALUE 0.000 | 161,632 | 2 | 0.000000 | ELEPHANT:MAP-INDEX 0.000 | 32,744 | 202 | 0.000000 | ELEPHANT:CURSOR-PNEXT-DUP 0.000 | 0 | 2 | 0.000000 | ELEPHANT:GET-INDEX 0.000 | 8,192 | 105 | 0.000000 | ELEPHANT:CURSOR-DELETE 0.000 | 0 | 2 | 0.000000 | ELEPHANT:KEY-FORM ---------------------------------------------------------- 2.166 | 46,207,880 | 705,639 | | Total estimated total profiling overhead: 0.57 seconds overhead estimation parameters: 0.0s/call, 8.12e-7s total profiling, 3.1e-7s internal profiling
seconds | consed | calls | sec/call | name ----------------------------------------------------------- 1.233 | 19,183,304 | 97,294 | 0.000013 | IMAGE 1.095 | 8,122,056 | 97,285 | 0.000011 | OFFSET 1.012 | 62,808,984 | 55,894 | 0.000018 | RECT 0.718 | 14,013,416 | 56,156 | 0.000013 | GET-INSTANCES-BY-VALUE 0.603 | 6,208,360 | 27,738 | 0.000022 | UPDATE 0.490 | 4,677,144 | 64,998 | 0.000008 | ELEVATION 0.241 | 2,653,496 | 28,970 | 0.000008 | VELOC 0.222 | 6,730,720 | 1 | 0.222339 | MAIN 0.156 | 8,248,720 | 1 | 0.156000 | CREATE-DATABASE 0.135 | 2,400,888 | 13,800 | 0.000010 | VISIBLE 0.077 | 216,976 | 41,538 | 0.000002 | RENDER 0.056 | 1,069,024 | 13,800 | 0.000004 | ACCEL 0.049 | 581,072 | 41,747 | 0.000001 | SURFACE 0.031 | 1,072,024 | 1 | 0.031000 | SETUP-REPL-STREAMS 0.016 | 49,128 | 1 | 0.016000 | CLOSE-DATABASE 0.016 | 957,280 | 208 | 0.000076 | GET-INSTANCE-BY-VALUE 0.016 | 352,600 | 102 | 0.000155 | ENTER 0.015 | 973,016 | 1 | 0.015000 | HANDLE-KEY-DOWN 0.000 | 0 | 1 | 0.000000 | TITLE-CAPTION 0.000 | 0 | 372 | 0.000000 | VELOC-X 0.000 | 0 | 313 | 0.000000 | VELOC-Y 0.000 | 0 | 1 | 0.000000 | USE-ROOT 0.000 | 8,192 | 28,078 | 0.000000 | CHILDREN 0.000 | 0 | 2 | 0.000000 | SIZE 0.000 | 69,552 | 201 | 0.000000 | ACTIVE 0.000 | 8,184 | 102 | 0.000000 | LEAVE 0.000 | 0 | 1 | 0.000000 | EXIT 0.000 | 0 | 478 | 0.000000 | ROOT 0.000 | 0 | 84,319 | 0.000000 | Y 0.000 | 16,352 | 84,429 | 0.000000 | X 0.000 | 0 | 142 | 0.000000 | INPUT-MODE 0.000 | 0 | 1 | 0.000000 | KEY-REPEAT ----------------------------------------------------------- 6.182 | 140,420,488 | 737,975 | | Total estimated total profiling overhead: 0.58 seconds overhead estimation parameters: 0.0s/call, 7.8200003e-7s total profiling, 3.38e-7s internal profiling Short description of the first several most expensive functions: image: Slot read containing a persisted vector, which is then accessed. offset: Slot read containing a complex number. rect: Transient slot operation. get-instances-by-value: From Elephant. update: Iterates over objects with a certain slot value (after sorting them according to a second slot), and recursively calls update on each. Additional before and after methods may do several slot reads or writes.
_______________________________________________ elephant-devel site list elephant-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/elephant-devel