Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

# Vector help

3 views

### Kevin Goodier

Feb 18, 1998, 3:00:00â€¯AM2/18/98
to

I have a list of length 32, and I'm going to be altering a couple of
elements in it multiple times (meaning I'll be making many many copies of
it). I'm thinking that a simple vector would be the most efficient (i'm
looking for FASTEST) way to go, but I can't for the life of me find a
built-in function to convert a list to a vector. Is there an easy and
efficient way to do this??

The list is being given to me, so I can't just create a vector instead
(unfortunately). Is a simple vector going to be significantly faster?

Thanks!

------------->
Kevin Goodier
bk...@cec.wustl.edu
http://students.cec.wustl.edu/~bkg2/

### Chuck Fry

Feb 18, 1998, 3:00:00â€¯AM2/18/98
to

Kevin Goodier <bk...@cec.wustl.edu> wrote:
>I have a list of length 32, and I'm going to be altering a couple of
>elements in it multiple times (meaning I'll be making many many copies of
>it). I'm thinking that a simple vector would be the most efficient (i'm
>looking for FASTEST) way to go, but I can't for the life of me find a
>built-in function to convert a list to a vector. Is there an easy and
>efficient way to do this??

The most generic way to create a vector from a list is:
(concatenate 'vector <list>)

Alternately, depending on the implementation and the list's size, you
can do:
(apply #'vector <list>)

In each case, the resulting vector is a copy of the list.

In Zetalisp on the MIT Lisp machines and their descendants, there were
facilities that allowed a CDR-coded (compacted) list to be referenced as
a vector. I sincerely doubt anyone currently implements this, since
CDR-coding seems to be consigned to the dustbin of history. Oh well,
memory's too cheap to bother saving these days, I guess.

>The list is being given to me, so I can't just create a vector instead
>(unfortunately). Is a simple vector going to be significantly faster?

When accessed randomly as a vector would be, yes. When iterated over in
a linear fashion, the difference is smaller. Even so, lists are still
slower because the reference to the next item always requires 2 memory
references with the usual linked-list format, instead of 1 for a vector.
Then there are the locality-of-reference impacts of the linked list on
the cache and paging systems. Two more reasons I miss CDR-coding, which

I once maintained a program that used lists to represent moderate size
(100-1000) numeric vectors, a ludicrous approach. The original coder
had bought into the "generic sequence" stuff in CLtL1, and instead of
stepping through the lists with DOLIST or equivalent, had used ELT and
DOTIMES instead! This changed an O(n) algorithm into an O(n^2)
algorithm, and slower even for small values of n because of the
the poor performance, not the coder! They were stunned with the
performance when I reimplemented this code with arrays.

I am convinced Lisp's worst enemies are the mediocre and poor Lisp
programmers who misunderstand and misuse the language, and those
ignorant souls who still believe that Lisp only has lists for data
structures. Sometimes they are the same people.

-- Chuck
--
Chuck Fry -- Jack of all trades, master of none
chu...@chucko.com (text only please), chuc...@home.com (MIME enabled),
chu...@gateway.idiom.com (SPAM ONLY)

### Kevin Goodier

Feb 18, 1998, 3:00:00â€¯AM2/18/98
to

In article <6cfsn2\$c55\$1...@shell5.ba.best.com>, chu...@shell5.ba.best.com
says...

> The most generic way to create a vector from a list is:
> (concatenate 'vector <list>)
>
> Alternately, depending on the implementation and the list's size, you
> can do:
> (apply #'vector <list>)

I'll look up both these methods right after this, but before I do, which
would you recommend? For a relatively small list (length=32, or
occasionally smaller), where the converting from a list to a vector is
performed often, which way is faster? Are they about the same?

> When accessed randomly as a vector would be, yes. When iterated over in
> a linear fashion, the difference is smaller. Even so, lists are still
> slower because the reference to the next item always requires 2 memory
> references with the usual linked-list format, instead of 1 for a vector.

Is there any downside to iterating over a vector rather than a list?
I'll have to do that, too, although random access will be the one more
heavily used.

> I am convinced Lisp's worst enemies are the mediocre and poor Lisp
> programmers who misunderstand and misuse the language, and those
> ignorant souls who still believe that Lisp only has lists for data
> structures. Sometimes they are the same people.

I didn't like LISP at first (oh, about 3 weeks ago), but it's growing on
me now. I've moved up to the average level (I spent 40 hours on one
program last week), and I rather like the language. There seem to be
lots of little things that, once you learn them, make life much easier
and much better. Vectors, for instance... I can't find any good info on
them on the web, and one of the Common LISP books I have doesn't even
mention them.

### Erik Naggum

Feb 19, 1998, 3:00:00â€¯AM2/19/98
to

* Kevin Goodier

| I have a list of length 32, and I'm going to be altering a couple of
| elements in it multiple times (meaning I'll be making many many copies of
| it). I'm thinking that a simple vector would be the most efficient (i'm
| looking for FASTEST) way to go, but I can't for the life of me find a
| built-in function to convert a list to a vector. Is there an easy and
| efficient way to do this??

I think

(make-array 32 :initial-contents <list>)

is the fastest and easiest way to convert a list of known length to a
vector of known size. I also have reason to expect

(make-array (length <list>) :initial-contents <list>)

to be faster than the other suggestions in the unknown length case.

| The list is being given to me, so I can't just create a vector instead
| (unfortunately). Is a simple vector going to be significantly faster?

well, there's faster and there's faster. accessing element n in a list
is an O(n) operation in the general case, whereas accessing element n in
a vector is an O(1) operation. the special case of accessing element n+1
when you last accessed element n is O(1) in both cases if you code well.

however, there are a few minor issues that affect the constants of these
upper limits to execution time. stepping over a list with DOLIST will
need to keep track of two values, your variable and an (opaque) variable
that holds the tail, and you will need to make two memory references, but
all the parameters of these operations are known, so you will not make
any function calls to obtain the CAR and CDR of the successive CONS cells
-- these accessors will be open-coded, the test for NIL is trivial, and
the two values typically go in registers. stepping over a vector of
unknown size with DOTIMES will need to keep track of the index into the
vector, test it against the size (with a function call), and will have to
do generic (as opposed to type-specialized) addition every time the index
is incremented, which is likely a function call. on top of this, you are
likely to force a function call to AREF to access the element, which will
make another test for the size of the array, forcing several more memory
references in this "faster" case. it may turn out that you could have
accesses two or three successive elements in a list by the time you have
accessed the first slot in a vector, at least as far as the traversal
skeleton is concerned.

if you want the most out of a vector traversal, you need to declare the
index to be a fixnum, declare the type and your best effort at the
dimension of the vector, and use the more specialized SVREF instead of
the more generic AREF if you can. then you need to compile the code with
a high SPEED and probably a low SAFETY setting to force open-coding of
all of these functions. in this case it will be as fast as the hardware
can bear, possibly even taking advantage of instructions that decrement a
counter register and branch on zero instead of incrementing, comparing,
and branch on equal. trust me, all of this stuff adds up real quick.

e.g., Allegro CL 4.3.1 expand (dotimes (i 100) (aref <vector> i)) into

(do ((i 0 (1+ i)))
((>= i 100))
(declare (type (integer 0 100) i))
(aref <vector> i))

but (dotimes (i (length <vector>)) (aref <vector> i)) is expanded into

(do ((#:g140 (length <vector>))
(i 0 (1+ i)))
((>= i #:g140))
(aref <vector> i))

so you would need to add your declaration to get equal code.

speed in Lisp is a difficult issue. it's hard to predict when the
compiler knows or doesn't know enough to generation the fastest available
code. sometimes, what works in the default cause is very fast, such as
in DOLIST, which knows all it needs to know, and sometimes it is not at
all fast, such as in the DOTIMES/AREF case, where the compiler needs to
know far more about your intentions than it is possible to communicate
with these simple forms.

however, if you're lucky, LOOP is heavily optimized in your compiler and
may do the right thing in both cases. LOOP/IN traverses a list and
LOOP/ACROSS traverses a vector. however, I don't know of a way to make
LOOP/ACROSS use SVREF instead of AREF when I know that the vector is
simple. any takers?

anyway, if you are concerned with speed, you have to consider your
hardware and your compiler, which to some people seem "un-Lispy", but
that is only because it is more natural to write correct code first than
to optimize the living daylight out of incorrect code. the compiler
cannot know your intentions unless you tell it, but it is free to assume
a lot worse than you might expect. (and strong typing is _not_ the
answer -- it's much worse to pretend to illuminate the compiler when
you're still in the dark yourself than to keep the compiler in the dark
with you.) most Lisp compilers come with profilers, call counters, and
other tools to help you decide when, where, and how to optimize. this
way you can make an informed estimate of the expected performance gains
very interesting exchanges in this newsgroup in the past that highlighted
the vastly different approaches to speeding up Lisp code, so don't assume
that there's a "last word" on this.

hope this helps.

#:Erik
--
God grant me serenity to accept the code I cannot change,
courage to change the code I can, and wisdom to know the difference.

### Rainer Joswig

Feb 19, 1998, 3:00:00â€¯AM2/19/98
to

Erik Naggum schrieb in Nachricht <30968599...@naggum.no>...

>* Kevin Goodier
>| I have a list of length 32, and I'm going to be altering a couple of
>| elements in it multiple times (meaning I'll be making many many copies of
>| it). I'm thinking that a simple vector would be the most efficient (i'm
>| looking for FASTEST) way to go, but I can't for the life of me find a
>| built-in function to convert a list to a vector. Is there an easy and
>| efficient way to do this??
>
> I think
>
>(make-array 32 :initial-contents <list>)

(coerce '(a b c) 'vector) => #(A B C)

### Howard R. Stearns

Feb 19, 1998, 3:00:00â€¯AM2/19/98
to

Kevin Goodier wrote:
> ...

> I didn't like LISP at first (oh, about 3 weeks ago), but it's growing on
> me now. I've moved up to the average level (I spent 40 hours on one
> program last week), and I rather like the language. There seem to be
> lots of little things that, once you learn them, make life much easier
> and much better. Vectors, for instance... I can't find any good info on
> them on the web, and one of the Common LISP books I have doesn't even
> mention them.

See the "Association of Lisp Users" site, currently at
http://www.elwood.com/alu
It includes guides to Lisp books organized by category, links to style
guides, tutorials, the newsgroup FAQ, and other Lisp lore.

For example, the style guide written by Mark Kantrowitz and Barry
vectors.

### Pierpaolo Bernardi

Feb 19, 1998, 3:00:00â€¯AM2/19/98
to

Kevin Goodier (bk...@cec.wustl.edu) wrote:
: In article <6cfsn2\$c55\$1...@shell5.ba.best.com>, chu...@shell5.ba.best.com
: says...
: > The most generic way to create a vector from a list is:
: > (concatenate 'vector <list>)
: >
: > Alternately, depending on the implementation and the list's size, you
: > can do:
: > (apply #'vector <list>)

Also:

(coerce <list> 'vector)

### Chuck Fry

Feb 19, 1998, 3:00:00â€¯AM2/19/98
to

Kevin Goodier <bk...@cec.wustl.edu> wrote:
>In article <6cfsn2\$c55\$1...@shell5.ba.best.com>, chu...@shell5.ba.best.com
>says...
>> The most generic way to create a vector from a list is:
>> (concatenate 'vector <list>)
>>
>> Alternately, depending on the implementation and the list's size, you
>> can do:
>> (apply #'vector <list>)

Ironically neither of my examples communicates the code's intent
clearly. The following does, and should probably be used in preference
to the above:
(coerce <list> 'vector)

The only caveat is that the spec for COERCE does not specify whether the
result is a new object, or the old object modified to suit. In part
this is because COERCE is allowed to return the original object if it
matches the type spec.

In my testing of this example on Allegro CL for Unix, COERCE returned a
new vector, leaving the original list unmolested. Better try this on

>I'll look up both these methods right after this, but before I do, which
>would you recommend? For a relatively small list (length=32, or
>occasionally smaller), where the converting from a list to a vector is
>performed often, which way is faster? Are they about the same?

Why not try them all on your own Lisp system? The TIME macro will tell
you which is faster. Be sure to time compiled code, not interpreted.

I strongly suspect that the conversion is not going to dominate your run
time, so I'd recommend using COERCE, as it most clearly communicates the
intent of the code. The APPLY hack is likely fastest, but will be
limited to vectors of length less than your implementation's value of
CALL-ARGUMENTS-LIMIT.

>Is there any downside to iterating over a vector rather than a list?
>I'll have to do that, too, although random access will be the one more
>heavily used.

Not that I'm aware of. I would expect iterating over a vector to be
faster in implementations with highly optimizing compilers.

>> I am convinced Lisp's worst enemies are the mediocre and poor Lisp
>> programmers who misunderstand and misuse the language, and those
>> ignorant souls who still believe that Lisp only has lists for data
>> structures. Sometimes they are the same people.
>

>I didn't like LISP at first (oh, about 3 weeks ago), but it's growing on
>me now. I've moved up to the average level (I spent 40 hours on one
>program last week), and I rather like the language. There seem to be
>lots of little things that, once you learn them, make life much easier
>and much better. Vectors, for instance... I can't find any good info on
>them on the web, and one of the Common LISP books I have doesn't even
>mention them.

My apologies if you thought this was directed at you! Yes, Common Lisp
is a big language, and it takes a while to learn all the subtleties. I
don't have a complaint with folks earnestly trying to improve their
command of the language.

But I have a serious beef with those folks who write bad CL code for a
living, and never bother to learn what the language is about.
Well-crafted CL code is rare in the applications I've seen over the 10
years CL has been widely available. I find it's because most of the
programmers responsible for the abominations just don't understand how
to use the language correctly, and either don't care to learn, or were
permanently warped by learning imperative languages first, or (worst)
don't really understand programming at all.

And IMHO, any CL book that fails to talk about vectors, arrays, and CLOS
should be burned. We've come a long way from Lisp 1.5, in fact CLOS was
the first object-oriented language to become an official standard! But
some people never get that message.

If I ever get around to writing a CL textbook, I will pretend lists
don't exist for at least the first several chapters. Not because that
will make it easier to teach C programmers Lisp (I doubt it will), but
because too many Lisp users learn the list datatype first and use it for
*everything*, without asking themselves if a more appropriate
representation exists.

### Mike Mcdonald

Feb 19, 1998, 3:00:00â€¯AM2/19/98
to

In article <6cfsn2\$c55\$1...@shell5.ba.best.com>,
chu...@shell5.ba.best.com (Chuck Fry) writes:

> Kevin Goodier <bk...@cec.wustl.edu> wrote:
>>I have a list of length 32, and I'm going to be altering a couple of
>>elements in it multiple times (meaning I'll be making many many copies of
>>it). I'm thinking that a simple vector would be the most efficient (i'm
>>looking for FASTEST) way to go, but I can't for the life of me find a
>>built-in function to convert a list to a vector. Is there an easy and
>>efficient way to do this??
>
> The most generic way to create a vector from a list is:
> (concatenate 'vector <list>)
>
> Alternately, depending on the implementation and the list's size, you
> can do:
> (apply #'vector <list>)

Why not the more straight forward:
(coerce <list> 'vector)

>>The list is being given to me, so I can't just create a vector instead
>>(unfortunately). Is a simple vector going to be significantly faster?
>

> When accessed randomly as a vector would be, yes. When iterated over in
> a linear fashion, the difference is smaller. Even so, lists are still
> slower because the reference to the next item always requires 2 memory
> references with the usual linked-list format, instead of 1 for a vector.

In common lisp, doesn't an AREF incur more than
one memory reference? Such as getting the length of
the vector from the vector's header and checking
whether the reference is in bounds?

Mike McDonald
mik...@mikemac.com

### Chuck Fry

Feb 19, 1998, 3:00:00â€¯AM2/19/98
to

In article <6ci3bp\$o...@hpmos.wv.mentorg.com>,

Mike Mcdonald <mik...@mikemac.com> wrote:
> In common lisp, doesn't an AREF incur more than
>one memory reference? Such as getting the length of
>the vector from the vector's header and checking
>whether the reference is in bounds?

Generally, yes. In some cases (such as LOOP/ACROSS), a smart compiler
could do the array header checks only once.

Thanks for catching this. Does the same apply to SVREF?

### Kevin Goodier

Feb 19, 1998, 3:00:00â€¯AM2/19/98
to

Chuck Fry (chu...@shell5.ba.best.com) says...

> Mike Mcdonald <mik...@mikemac.com> wrote:
> > In common lisp, doesn't an AREF incur more than
> >one memory reference? Such as getting the length of
> >the vector from the vector's header and checking
> >whether the reference is in bounds?
>
> Generally, yes. In some cases (such as LOOP/ACROSS), a smart compiler
> could do the array header checks only once.
>
> Thanks for catching this. Does the same apply to SVREF?

I'm using SVREF in my implementation now. So, anyone, *does* the same
apply to it as AREF?

I ran a test case, one with lists and NTH being used, and another with
vectors and SVREF being used. To my dismay, they came up with the same
time (on approx 1800 vectors/lists being created, and each one having its
elements randomly-accessed 2 or 3 times). However, this was NOT compiled
code. And I haven't added the function yet that is going to have to loop
across every item in the vector..

By the way, what is the fastest way to copy a vector? I'm using COPY-SEQ
now -- anything better available?

### Kevin Goodier

Feb 19, 1998, 3:00:00â€¯AM2/19/98
to

Barry Margolin (bar...@bbnplanet.com) says...
> How big were the vectors/lists? Accessing the nth element of a list is
> O(n), while it's O(1) for vectors, so the difference in speed will depend
> on the average index. With interpreted code and small arrays/sequences,
> the interpreter overhead may be hiding the difference in access times.
>

The lists were 32 elements long, so I bet the overhead WAS interfering.
This leads me to my question: how does one compile LISP code?

From what I understand, I should type (COMPILE-FILE "c.lsp"), which will
produce a file (by default) called "c.o".... should I then type (LOAD

Because when I do that, it attempts to load, then crashes out of the LISP
environment with a "segmentation fault" error (yeck, C++ memories...). I
got many, many warnings when it compiled (unknown global vars, stuff like
that), but no errors that I could detect. Once I get my code completed
and cleaned up, I'll try it again... but I was just wondering if I was
doing something wrong or not. If it matteres, I'm using AKCL running in
a Solaris environment.

### Barry Margolin

Feb 20, 1998, 3:00:00â€¯AM2/20/98
to

In article <6chuoh\$s2s\$1...@shell5.ba.best.com>,

Chuck Fry <chu...@shell5.ba.best.com> wrote:
>In my testing of this example on Allegro CL for Unix, COERCE returned a
>new vector, leaving the original list unmolested. Better try this on

Since the types LIST and VECTOR are disjoint, this coercion *must* return a
fresh vector. Any implementation that doesn't is severely broken. Yes, I
believe this even goes for the Symbolics implementation that's able to
treat a CDR-coded list as a vector; that type of coercion requires use of
implementation-specific features to accomplish.

--
Barry Margolin, bar...@bbnplanet.com
Support the anti-spam movement; see <http://www.cauce.org/>
Please don't send technical questions directly to me, post them to newsgroups.

### Barry Margolin

Feb 20, 1998, 3:00:00â€¯AM2/20/98
to

Kevin Goodier <bk...@cec.wustl.edu> wrote:
>I ran a test case, one with lists and NTH being used, and another with
>vectors and SVREF being used. To my dismay, they came up with the same
>time (on approx 1800 vectors/lists being created, and each one having its
>elements randomly-accessed 2 or 3 times). However, this was NOT compiled
>code. And I haven't added the function yet that is going to have to loop
>across every item in the vector..

How big were the vectors/lists? Accessing the nth element of a list is

O(n), while it's O(1) for vectors, so the difference in speed will depend
on the average index. With interpreted code and small arrays/sequences,
the interpreter overhead may be hiding the difference in access times.

--

Feb 20, 1998, 3:00:00â€¯AM2/20/98
to Kevin Goodier

You're problem is that, almost certainly, you're using CC v3.0.1 to
try to compile your code (it happens behind the scenes). You need
to remove that from your path (pkgrm sc) and add sc_3.1, which
works. Why this is, I don't know, as it won't work with sc_4.0 either...
go figure.....

Kevin Goodier wrote:

> Barry Margolin (bar...@bbnplanet.com) says...

> > How big were the vectors/lists? Accessing the nth element of a list is
> > O(n), while it's O(1) for vectors, so the difference in speed will depend
> > on the average index. With interpreted code and small arrays/sequences,
> > the interpreter overhead may be hiding the difference in access times.
> >
>

### Kevin Goodier

Feb 20, 1998, 3:00:00â€¯AM2/20/98
to

> You're problem is that, almost certainly, you're using CC v3.0.1 to
> try to compile your code (it happens behind the scenes). You need
> to remove that from your path (pkgrm sc) and add sc_3.1, which
> works. Why this is, I don't know, as it won't work with sc_4.0 either...
> go figure.....

<scratching my head> Why does the C++ compiler version affect the
compilation of my LISP code??!

Feb 20, 1998, 3:00:00â€¯AM2/20/98
to Kevin Goodier

Because it generates C code, and compiles that. If you watch the
directory you're working in while you're in the compile-file
process, you'll see the C files. Kinda neat, actually, and an
interesting way around actually having a native LISP compiler.
There may be some, but that's not how akcl (at least this version)
works.

To the newsgroup at large: is there any way to link the resultant
.o file? It seems to be lacking a library, but I haven't been able to
figure our which....

### Howard R. Stearns

Feb 20, 1998, 3:00:00â€¯AM2/20/98
to

CLOS provides for instances to be side-effected in a way that changes
their class. Would it be legal for coerce to do the same?

Examples might be bignums/simple-bit-vectors and
cdr-coded-lists/simple-vectors.

As far as I can see, the spec for COERCE neither mentions the words
"fresh" or "new", nor prohibits side-effects.

Perhaps some other part of the spec says that side-effects are
prohibited unless specifically allowed? (If there isn't such a
statement, their problably should be.)

Barry Margolin wrote:
>
> In article <6chuoh\$s2s\$1...@shell5.ba.best.com>,
> Chuck Fry <chu...@shell5.ba.best.com> wrote:
> >In my testing of this example on Allegro CL for Unix, COERCE returned a
> >new vector, leaving the original list unmolested. Better try this on
> >your implementation to be sure.
>
> Since the types LIST and VECTOR are disjoint, this coercion *must* return a
> fresh vector. Any implementation that doesn't is severely broken. Yes, I
> believe this even goes for the Symbolics implementation that's able to
> treat a CDR-coded list as a vector; that type of coercion requires use of
> implementation-specific features to accomplish.
>

### Barry Margolin

Feb 20, 1998, 3:00:00â€¯AM2/20/98
to

In article <34EDD3...@elwood.com>,

Howard R. Stearns <how...@elwood.com> wrote:
>CLOS provides for instances to be side-effected in a way that changes
>their class. Would it be legal for coerce to do the same?

I don't think so. The CLOS CHANGE-CLASS function is clearly different from
COERCE, as it is specifically documented to modify the object in place, so
that it's still EQ to itself.

On the other hand, for all the builtin types, if two objects are of
disjoint types, they can't be EQ.

Note also that COERCE is not specified to call CHANGE-CLASS

>Examples might be bignums/simple-bit-vectors and
>cdr-coded-lists/simple-vectors.
>
>As far as I can see, the spec for COERCE neither mentions the words
>"fresh" or "new", nor prohibits side-effects.

The description of COERCE goes into detail about how each of the allowed
coercions is done. Except where the original object is already of the
result type, they all imply that a new object should be returned.

>Perhaps some other part of the spec says that side-effects are
>prohibited unless specifically allowed? (If there isn't such a
>statement, their problably should be.)

While this would be a good idea, I think it's somewhat implicit. If
unconstrained side effects are permitted, the standard is virtually
meaningless. For instance, suppose an implementation had the following
side effect: any time you SETQ a variable whose name begins with "A" to a
number, the variable with the "A" replaced with "B" will be assigned the
same value. This would result in the following:

(setq baa 1)
(setq aaa 10)
baa => 10

If we can't even depend on variables retaining their values, what can we
depend on?

Note that dictionary entries in the ANSI spec have "Side Effects" sections,
and the implication should be that these are the only side effects
permitted.

### Rainer Joswig

Feb 22, 1998, 3:00:00â€¯AM2/22/98
to

Kevin Goodier schrieb in Nachricht ...

>doing something wrong or not. If it matteres, I'm using AKCL running in
>a Solaris environment.

Isn't AKCL superseded by GCL (which is based on AKCL)?

### Marco Antoniotti

Feb 23, 1998, 3:00:00â€¯AM2/23/98
to

bk...@cec.wustl.edu (Kevin Goodier) writes:

> Barry Margolin (bar...@bbnplanet.com) says...
> > How big were the vectors/lists? Accessing the nth element of a list is
> > O(n), while it's O(1) for vectors, so the difference in speed will depend
> > on the average index. With interpreted code and small arrays/sequences,
> > the interpreter overhead may be hiding the difference in access times.
> >
>
> The lists were 32 elements long, so I bet the overhead WAS interfering.
> This leads me to my question: how does one compile LISP code?
>
> From what I understand, I should type (COMPILE-FILE "c.lsp"), which will
> produce a file (by default) called "c.o".... should I then type (LOAD

Note that you can also do

(compile 'function-name)

at the interpreter prompt.

> Because when I do that, it attempts to load, then crashes out of the LISP
> environment with a "segmentation fault" error (yeck, C++
> memories...). I
> got many, many warnings when it compiled (unknown global vars, stuff like
> that), but no errors that I could detect. Once I get my code completed
> and cleaned up, I'll try it again... but I was just wondering if I was

> doing something wrong or not. If it matteres, I'm using AKCL running in
> a Solaris environment.

descendant called GCL, or - better yet - CMUCL from
http://www.cons.org.

The fact that you get a lot of warnings also induces me to think that
your code may be not Lisp-ish enough. In this case using the CMUCL
compiler will definitively be of help (beside producing even more
warnings :) ).

--
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 80 79 23, fax. +39 - (0)6 - 68 80 79 26

### David D. Smith

Mar 4, 1998, 3:00:00â€¯AM3/4/98
to

bk...@cec.wustl.edu (Kevin Goodier) wrote:

> I have a list of length 32, and I'm going to be altering a couple of
> elements in it multiple times (meaning I'll be making many many copies of
> it). I'm thinking that a simple vector would be the most efficient (i'm
> looking for FASTEST) way to go, but I can't for the life of me find a
> built-in function to convert a list to a vector. Is there an easy and
> efficient way to do this??

(coerce list32 'vector)

> The list is being given to me, so I can't just create a vector instead
> (unfortunately). Is a simple vector going to be significantly faster?

Depends. If you can destroy the original list and you only want to modify
a few elements then you might wnat to bind those conses...

(let ((consx (nthcdr a list32))
(consy (nthcdr b list32))) ; or LET* ... (nthcdr (- b a) consx)
(symbol-macrolet ((x (car consx))
(y (car consy)))
;; Reference X and Y in constant time, e.g.
(setq x (1+ y))
...

d

0 new messages