unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Optimizing record accessors
@ 2007-08-07 15:00 Ludovic Courtès
  2007-08-08 15:08 ` Ludovic Courtès
  2007-08-21  0:10 ` Kevin Ryde
  0 siblings, 2 replies; 4+ messages in thread
From: Ludovic Courtès @ 2007-08-07 15:00 UTC (permalink / raw)
  To: guile-devel

[-- Attachment #1: Type: text/plain, Size: 1903 bytes --]

Hi,

Currently, accessing a record is slow.  Consider this sample:

===File ~/src/guile-core/,,record-prof.scm==================
(use-modules (statprof)
             (srfi srfi-9))

(define-record-type <stuff>
  (make-stuff x y z)
  stuff?
  (x  stuff-x)
  (y  stuff-y)
  (z  stuff-z))

(define stuff (make-stuff 1 2 3))

(with-statprof #:hz 20 #:loop 1000000
  (stuff-x stuff))
============================================================

(SRFI-9 uses the record layer.)

Here is what we observe:

  $ ./pre-inst-guile ,,record-prof.scm
  %     cumulative   self             
  time   seconds     seconds      name
   33.33      2.95      0.98  #{statprof\ 0}#
   27.45      0.81      0.81  record-type-descriptor
   17.65      1.91      0.52  stuff-x
   15.69      1.39      0.46  %record-type-check
    3.92      0.93      0.12  eq?
    1.96      0.06      0.06  not
  ---
  Sample count: 51
  Total time: 2.95 seconds (9/25 seconds in GC)

Changing `record-accessor' as in the attached file yields this:

  $ ./pre-inst-guile ,,record-prof.scm
  %     cumulative   self             
  time   seconds     seconds      name
   46.88      1.89      0.89  #{statprof\ 0}#
   43.75      0.95      0.83  stuff-x
    6.25      0.12      0.12  eq?
    3.13      0.06      0.06  not
  ---
  Sample count: 32
  Total time: 1.89 seconds (1/5 seconds in GC)

A 36% improvement.

Type-safety is still guaranteed (e.g., `struct-vtable' will fail if OBJ
is not a struct), though not as precisely (e.g., instead of a
`not-a-record' error, we get a `wrong-type-arg' error in
`struct-vtable').  Thus, for instance, `srfi-9.test' will have to be
relaxed as to the exception type expected (which is reasonable anyway
since SRFI-9 does not specify error types).

I believe the improvement is worth the change, otherwise people may end
up using vectors or their own record abstraction.

Ok to commit?

Thanks,
Ludovic.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Optimized record accessors --]
[-- Type: text/x-patch, Size: 1205 bytes --]

--- orig/ice-9/boot-9.scm
+++ mod/ice-9/boot-9.scm
@@ -429,7 +429,7 @@
 (define (record-predicate rtd)
   (lambda (obj) (and (struct? obj) (eq? rtd (struct-vtable obj)))))
 
-(define (%record-type-check rtd obj)  ;; private helper
+(define (%record-type-error rtd obj)  ;; private helper
   (or (eq? rtd (record-type-descriptor obj))
       (scm-error 'wrong-type-arg "%record-type-check"
 		 "Wrong type record (want `~S'): ~S"
@@ -441,8 +441,9 @@
     (if (not pos)
 	(error 'no-such-field field-name))
     (local-eval `(lambda (obj)
-		   (%record-type-check ',rtd obj)
-		   (struct-ref obj ,pos))
+                   (if (eq? (struct-vtable obj) ,rtd)
+                       (struct-ref obj ,pos)
+                       (%record-type-error ,rtd obj)))
 		the-root-environment)))
 
 (define (record-modifier rtd field-name)
@@ -450,7 +451,8 @@
     (if (not pos)
 	(error 'no-such-field field-name))
     (local-eval `(lambda (obj val)
-		   (%record-type-check ',rtd obj)
-		   (struct-set! obj ,pos val))
+                   (if (eq? (struct-vtable obj) ,rtd)
+                       (struct-set! obj ,pos val)
+                       (%record-type-error ,rtd obj)))
 		the-root-environment)))
 

[-- Attachment #3: Type: text/plain, Size: 143 bytes --]

_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Optimizing record accessors
  2007-08-07 15:00 Optimizing record accessors Ludovic Courtès
@ 2007-08-08 15:08 ` Ludovic Courtès
  2007-08-21  0:10 ` Kevin Ryde
  1 sibling, 0 replies; 4+ messages in thread
From: Ludovic Courtès @ 2007-08-08 15:08 UTC (permalink / raw)
  To: guile-devel

Hi,

ludo@gnu.org (Ludovic Courtès) writes:

> Ok to commit?

Applied to both branches.

Thanks,
Ludovic.



_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Optimizing record accessors
  2007-08-07 15:00 Optimizing record accessors Ludovic Courtès
  2007-08-08 15:08 ` Ludovic Courtès
@ 2007-08-21  0:10 ` Kevin Ryde
  2007-08-21  7:58   ` Ludovic Courtès
  1 sibling, 1 reply; 4+ messages in thread
From: Kevin Ryde @ 2007-08-21  0:10 UTC (permalink / raw)
  To: guile-devel

ludo@gnu.org (Ludovic Courtès) writes:
>
> Changing `record-accessor' as in the attached file yields

Gets rid of one scheme function call in the normal case does it?

I expect an apply-able smob thingie would be fastest (and smaller too)
for accessors and modifiers, if anyone felt like going down that track.
Probably quite worthwhile on the general principle of getting low-level
bits running fast.

> Type-safety is still guaranteed (e.g., `struct-vtable' will fail if OBJ
> is not a struct), though not as precisely (e.g., instead of a
> `not-a-record' error, we get a `wrong-type-arg' error in
> `struct-vtable').

As long as it's still `wrong-type-arg' it ought to be ok.  If the whole
lot goes into C at some stage then the errors will be easier to control.


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Optimizing record accessors
  2007-08-21  0:10 ` Kevin Ryde
@ 2007-08-21  7:58   ` Ludovic Courtès
  0 siblings, 0 replies; 4+ messages in thread
From: Ludovic Courtès @ 2007-08-21  7:58 UTC (permalink / raw)
  To: Kevin Ryde; +Cc: guile-devel

Hi,

Kevin Ryde <user42@zip.com.au> writes:

> Gets rid of one scheme function call in the normal case does it?

Two calls, because `record-type-check' called `record-type-descriptor'.

> I expect an apply-able smob thingie would be fastest (and smaller too)
> for accessors and modifiers, if anyone felt like going down that track.
> Probably quite worthwhile on the general principle of getting low-level
> bits running fast.

Yes, probably the right solution.  I thought about it but then didn't
feel like writing C.  ;-)

> As long as it's still `wrong-type-arg' it ought to be ok.

It was either `wrong-type-arg' or `not-a-record', which was not
documented.  Now, it's always `wrong-type-arg'.

Thanks,
Ludovic.


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-08-21  7:58 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-07 15:00 Optimizing record accessors Ludovic Courtès
2007-08-08 15:08 ` Ludovic Courtès
2007-08-21  0:10 ` Kevin Ryde
2007-08-21  7:58   ` Ludovic Courtès

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).