Message 1 of 6
Dictionary vs Ldata speed
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Why is dictionary is slower than ldata?
Here is an example of dictionary usage code.
;;;;;;;~~~~~~~~~~~~~~~~~~~~~~~~~~~~;;;;;;;
;;;;;;; The two working functions: ;;;;;;;
;;;;;;;____________________________;;;;;;;
;;
;;Sample use:
;; (dict-put "mydict" "mykey" '(1 (2 ("3" (44.4) (5.5 6.6 7.7) 8)) 999999))
;; (dict-get "mydict" "mykey")
;;POSSIBLE IMPROVEMENTS:
;; implement dict-append ( APPEND PREPEND )
;; Get A [Key] Value From Dictionary [Name]
(defun dict-get ( name key ) ;; name and key As strings
(x-relist ;; decode the data!
(cddr (member '(100 . "AcDbXrecord") ;; new (280) code group in r15
(dict-getrawdata name key)))))
;; Put A [Val]ue Into [Name] Dictionary Under [Key]
;; Dictionary is created automatically if was not existing
;; three arguments As strings
;; NAME may also be an entity name of some existing dictionary
(defun dict-put ( name key val )
(dict-clear name key) ;; clear the old value under this Key
(dictadd
(setq name (cond ((dict-name name)) ((dict-new name)) ))
key
(entmakex
(cons '(0 . "XRECORD")
(cons '(100 . "AcDbXrecord")
(x-enlist val)))) ) ;; encode the data!
name ) ;; return the dictionary altered
;;;;;;;~~~~~~~~~~~~~~~~~~~~~~~~~~~~;;;;;;;
;; XDICTIONARY SUPPORT
;; two more similar functions to use:
;;;;;;;~~~~~~~~~~~~~~~~~~~~~~~~~~~~;;;;;;;
(defun xdict-put ( ename key val )
(addxdict ename (dict-put nil key val)))
(defun xdict-get ( ename key )
(dict-get (cdr (assoc 360 (entget ename))) key))
;;;;;;; utility functions in use ;;;;;;;
;; a general utility -- pop first value off the list
(defun pop (a / b)
(setq b (eval a))
(set a (cdr b))
(car b))
;; general functions re/en-list, just to try things out
;; re-list can be also used in decoding xdata
(defun re-list ( lst / tok )
(re-list-aux))
(defun re-list-aux()
(cond
((atom lst) lst)
((/= "}" (setq tok (pop 'lst)))
(cons (if (= "{" tok) (re-list-aux) tok)
(re-list-aux)))))
(defun en-list ( lst )
(cond
((null lst) lst)
((atom lst) (list lst))
((cons "{" ;; add the markers around the list!
(reverse
(cons "}"
(reverse
(apply 'append ;; open the lists
(mapcar 'en-list lst) ;; recursion!
))))))))
;; a special encoding function for Xrecords to be used in dictionaries
(defun x-enlist ( lst ) ;; encode!
(cond
((null lst) lst)
((atom lst) ;; automatic code groups
(cond
((= 'REAL (type lst))
(list (cons 40 lst)))
((= 'INT (type lst))
(if ;; special handling of long integers
(< -32768 lst 32767)
(list (cons 70 lst))
(list (cons 41 (float lst)))))
((= 'STR (type lst))
(list (cons 1 lst)))
(T nil)))
((and (cdr lst) (atom (cdr lst)))
(list lst)) ;; pass dotted pair AS IS -- must be valid!!
((and (= (length lst) 3)
(apply 'and (mapcar 'numberp lst)))
(list (cons 10 lst)))
((cons '(2 . "{")
(reverse
(cons '(2 . "}")
(reverse
(apply 'append
(mapcar 'x-enlist lst) ))))))))
(defun x-relist ( lst / tok ) ;; decode it!
(car (x-relist-aux)))
(defun x-relist-aux()
(cond
((null lst) nil)
((not (equal '(2 . "}") (setq tok (pop 'lst))))
(cons (if (equal '(2 . "{") tok)
(x-relist-aux)
(cond ;; special processing of TOK to recover
((= 41 (car tok)) ;; long integers back
(fix (cdr tok)))
(T
(cdr tok)))
)
(x-relist-aux)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; dictionary functions for R14
;; POSSIBLE IMPROVEMENTS: support trees of dictionaries
;; now: all custom dictionaries are under the Root.
;;
;; Get Dictionary Object Name From Root Dictionary
(defun dict-name ( name ) ;; name As string or ename of exist dict
(cond
( (= 'STR (type name))
(cdr (assoc -1 (dictsearch (namedobjdict) name))))
( (and (= 'ENAME (type name))
(= "AcDbDictionary" (cdr (assoc 100 (entget name)))) )
name )))
;; Remove Dictionary [Name] From Root Dictionary
(defun dict-remove ( name / d0 ) ;; name As string
(if (dictsearch (Setq d0 (namedobjdict)) name)
(dictremove d0 name))
)
;; Make A New Empty Dictionary and put into into Root; Reset Existing.
(defun dict-new ( name / d0 ) ;; name As string
(cond
( (/= 'STR (type name))
(dict-new-orphan) )
('t
(if (dictsearch (Setq d0 (namedobjdict)) name)
(dictremove d0 name))
(dictadd d0 name
(dict-new-orphan) ))
))
;; (dict-new-ex parent name) parent := ROOT | ename (dict or reg for xdict)
(defun dict-new-orphan ()
(entmakex '((0 . "DICTIONARY")(100 . "AcDbDictionary"))))
;; List A Dictionary As Pairs {Name . Object Name}
(defun dict-list ( dname / d nl ) ;; dname As object name or string else ROOT
(cond
((and (Setq d (cond
((= 'ENAME (type dname))
dname)
((= 'STR (type dname))
(dict-name dname))
(T (namedobjdict))))
(Setq d (entget d)))
(while (setq d (member (assoc 3 d) d))
(if (or (= 350 (caadr d)) ;; regular dict
(= 360 (caadr d)) ;; extension dict
)
(setq nl (cons (cons (cdar d) (cdadr d)) nl)))
(setq d (cdr d)))
(reverse nl))))
;; Get Raw [Name] Dictionary Data for [Key]
(defun dict-getrawdata ( name key / d ) ;; name and key As strings
(cond
((='STR (type name))
(if (setq d (dict-name name))
(dictsearch d key)))
((='ENAME (type name))
(dictsearch name key) )
( (dictsearch (namedobjdict) key) )))
;; Clear The [Key] From Dictionary [Name]
(defun dict-clear ( name key / d) ;; name and key As strings
(if (setq d (dict-name name))
(dictremove d key)))
;; add xdictionary DK into the carrier entity data ECD
;; you can use it like (addxdict _entname_ (dict-put nil _key_ _val_))
;; eg. (addxdict (tblobjname"layer""0") (dict-put nil "MYDATA" 1.23))
;; to associate some data with layer "0".
;; you'll retrieve this data later with
;; (setq d (cdr(assoc 360 (entget (tblobjname "layer""0")))))
;; and
;; (dict-get d _key_)
(defun addxdict (ECD DK / TT)
(cond
( (= 'ENAME (type ecd))
(addxdict (entget ecd) dk) )
( (or (atom ecd) (atom (car ecd)) (not (atom (cdar ecd))))
nil )
( (= 'STR (type dk))
(addxdict ecd (dictsearch (namedobjdict) dk)) )
( (/= 'ENAME (type dk))
nil )
( (/= "AcDbDictionary" (cdr (assoc 100 (entget dk))))
nil )
( (assoc 102 ecd)
;; there already is an extension dictionary attached to this entity
;; can I prepend another dictionary into it?? No! :-(
(while (/= (caar ecd) 102)
(setq tt (cons (car ecd) tt)
ecd (cdr ecd)))
(setq tt (cons (car ecd) tt) ;; {
ecd (cdr ecd))
(while (/= 102 (caar ecd)) ;; }
(setq ecd (cdr ecd)))
(setq ecd (cons (cons 360 dk) ecd) )
(while tt
(setq ecd (cons (car tt) ecd)
tt (cdr tt)))
(entmod ecd))
( (assoc 100 ecd)
(while (/= (caar ecd) 100)
(setq tt (cons (car ecd) tt)
ecd (cdr ecd)))
(setq ecd
(cons (quote (102 . "{ACAD_XDICTIONARY"))
(cons (cons 360 dk)
(cons (quote (102 . "}")) ecd))))
(while tt
(setq ecd (cons (car tt) ecd)
tt (cdr tt)))
(entmod ecd))
))
;; EOF SaveData.lsp
(setq startRunTime (getvar 'millisecs))
(repeat 1000 (vlax-ldata-put "Test" "Test" '(1 (2 ("3" (44.4) (5.5 6.6 7.7) 8)) 999999)))
(rtos (/ (- (getvar 'millisecs) startRunTime) 1000.0) 2 2)
(setq startRunTime (getvar 'millisecs))
(repeat 1000 (dict-put "mydict" "mykey" '(1 (2 ("3" (44.4) (5.5 6.6 7.7) 8)) 999999)))
(rtos (/ (- (getvar 'millisecs) startRunTime) 1000.0) 2 2)
The ldata is much faster. Any idea?