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

Reply via email to