freenode/#lisp - IRC Chatlog
Search
4:15:10
aeth
when a DEFUN is under a LET instead of a PROGN (or nothing), then it no longer counts as top-level, so it can actually be slower
4:16:12
aeth
There are a handful of other top-level forms, most notably eval-when: http://www.lispworks.com/documentation/HyperSpec/Body/03_bca.htm
4:16:53
fwoaroof[m]
(I know non-local variable access can have a significant performance impact in python)
4:17:59
beach
Accessing closed-over variables can be slower. It depends on the compiler and how those variables are used.
4:18:46
fwoaroof[m]
I suspected that: in python, it's something like local variables are looked up by indexing into an array, global variables are looked up in a hash-map
4:19:51
aeth
Well, it's more complicated in CL because only dynamic/special variables or constants are portably global, although other globals might exist.
4:23:13
beach
For special variables, you can have deep binding or shallow binding. With shallow binding, and if your implementation uses threads, each variable has a current-value slot, probably in the reified thread object. With deep binding, you have to search the dynamic environment for the latest binding.
4:24:21
beach
The global value of a special variable (which is shared among all threads) a typical implementation has a slot in the symbol for it.
4:27:21
beach
A closed-over variable becomes part of the static environment of the function. And the static environment is passed as an implicit argument to the function. In the worst case, the value would then be kept inside a "cell" in the static environment. So you have two memory accesses to reach it, whereas an argument may be passed in a register.
4:27:49
beach
But if the closed-over variable is not assigned to after creation, the cell can be avoided.
4:28:29
beach
And the compiler can pass the static environment in different ways to avoid some overhead.
4:35:30
beach
So even though x is read-only, it is not the same each time in the anonymous function.
4:36:27
beach
Once it has been accessed there, it can be put in a register of course, if that is what you mean.
4:37:18
fwoaroof[m]
I don't think I was thinking clearly enough: I was thinking that, in some cases you could transform the inner lambda to something like (lambda (y) (+ 1 y))
4:37:59
beach
That would be possible only if you have something like (let ((x 1)) (lambda (y) (+ x y)))
4:41:40
borei
don't know, looks like im missing something very fundamental, and without it i can build full picture
4:42:37
borei
im looking at the macroexpand now - main and biggest difference is how function is accessing "nodes" array
4:43:56
borei
in second case - it's not parameter, and it's not local for the function var, so it need to looked up at higher level. higher level is "let"
4:46:04
borei
is there an option to make that nodes variable "like local" for the function defined in macro ?
4:47:13
borei
hmm, but that is not option in terms of performance because i need to call "let" every time
4:54:50
fwoaroof[m]
Whether or not the binding is a lexical binding depends on whether the variable has been declared special
4:56:40
borei
so with every call it will be creating lexical scope, then destroy it. i did try it yesterday. maybe was using it wrong, but result was even wors
5:01:00
fwoaroof[m]
Cool, I guess you have to decide whether the performance is worth the cost of passing an extra argument around
5:01:40
fwoaroof[m]
I'm not an expert at optimizing CL, though: there maybe some way of putting a LET inside the DEFUN and then declaring nodes DYNAMIC-EXTENT to get some more speed
5:04:01
borei
actually discussion was pretty useful for me, now i understand why im getting a bit better performance introducing one more function - it allows to reduce number of lookups to static environment.
5:04:19
beach
If some object is not passed as an argument, it has to be stored somewhere in the function object, or in a place that is accessible to the code of the function. That access requires a memory access. I don't see how you can get around this.
5:05:46
beach
I guess I should act upon the suggestion of doing a series of presentations for the online Lisp meeting, with the subject how a Common Lisp compiler works.
5:43:28
beach
In my opinion, programmers need to know about compiler design. Not so much in order to create fast code, but in order to avoid guessing what the compiler will do, and in the process, making their code less maintainable. But there are cases, like this one, where such knowledge is needed for creating fast code.
5:53:16
fwoaroof[m]
Yeah, I've been slowly discovering in my professional career why the old lisp books cover the topics they do
5:53:38
fwoaroof[m]
Things like continuations and language design are surprisingly relevant to day-to-day programming
5:57:42
seok38
fwoaroof[m] yeah, for books on other specific languages I wouldn't trust stuff that is printed before 2012
10:50:08
p_l
fwoaroof[m]: dynamic-extent doesn't have to be respected, but generally it's suggestion that it's similar to stack allocation, so it's less of a speed optimization and more space optimization
10:51:02
p_l
non-consing code also tends to keep to function arguments and return values a lot, but to be honest when looking for that I'
12:16:31
Josh_2
hmm I have a minor problem. Im trying to create my CLIM interface for an app, and all of the output is sent to *standard-output*, however I guess the backend is going to have to run in a different thread and I will have to override the default value of *standard-output* to be a different output stream so I can display the content in a different pane. Is it going to be safe for me to read from the stream on one thread and write on
12:16:31
Josh_2
another without using a lock?? or am I gonna have to go replace all of my instances of format with one that grabs a lock first?
12:18:07
Josh_2
I wish to run the backend with or without my CLIM interface, so I don't want to go messing with it all that much
12:18:33
Bike
if it came down to that you could just have a stream object that handles locking itself, probably, so the rest of your code wouldn't have to change
12:22:38
phoe
ACTION thinks of a world in which SIGNAL automatically placed a MUFFLE restart around the signaling site for all non-serious-conditions that would work in the same way as MUFFLE-WARNING does for warnings
12:25:17
phoe
basically, "ok, I took care of this, I don't want any outer signal handlers to execute, please carry on with the standard execution flow"
12:25:53
phoe
I mean, it's trivial to write a SIGNAL* function that does exactly this, but a short discussion with someone on the Dylan condition system sparked this thought in my head
12:27:32
jackdaniel
Josh_2: if you use the *standard-output* from inside the display function, then you are not accessing the it from "foreign" thread
12:28:13
jackdaniel
generally using streams asynchronously from a different thread is risky at best (i.e CCL signals an error)
12:28:55
jackdaniel
currently McCLIM streams are *not* thread safe, however I have plans to change that by scheduling asynchronous operations as events, which will be later "properly" handled in the stream-specific thread when dequeued
12:29:55
Josh_2
jackdaniel: well I am not using *standard-output* I have my own output-stream I have created as a slot on my frame which I wish to use in place of *standard-output* with (let ((*standard-output* output-stream ... etc
12:33:21
pve
is there an actual document or wiki for the Hypothetical Future Revision, or is it just a joke?
12:34:21
jackdaniel
(clim:define-application-frame foo () ((my-stream :initform /whatever/ :reader my-stream)) …) (defmethod clim:frame-standard-output ((frame foo)) (my-stream frame))
12:36:21
phoe
there's much more important stuff to do than working on the hypothetical future revision though
15:37:45
jmercouris
Instead of class B extending class A, I want class A to somehow get the properties of class B
15:38:12
jmercouris
I mean that I want the method that specializes on class B, to also get invoked for class A objects
15:41:32
phoe
that's one obvious upside of CLOS being a runtime object system as opposed to being a compile-time object system