LINUX.ORG.RU

scheme-mode и define

 , ,


1

2

Хочу изучить диалект лиспа scheme, взял книжку «Структура и интерпретация компьютерных программ». Включаю scheme-mode в емаксе, выполняю простейший пример:

 (define size 2) 
выполняю (^x^e), выводит ошибку - void function define. Что я делаю не так?


Ответ на: комментарий от korvin_

Обнаружил косяк: горутины шлют ответ в один канал, а не в один из 100 channels, в отличие от. Поправил Go-код:

package main

import (
	"fmt"
	"math/rand"
	"time"
)

type signal struct{}

const (
	NCHANNELS = 100
	NTHREADS  = 100000
)

var channels = makeChannels(NCHANNELS)

func pickChannel() chan signal {
	return channels[rand.Intn(NCHANNELS)]
}

func startThread() {
	time.Sleep(time.Millisecond * 100)
	pickChannel() <- signal{}
}

func makeChannels(n int) []chan signal {
	channels := make([]chan signal, n)
	for i := range channels {
		channels[i] = make(chan signal)
	}
	return channels
}

func main() {
	rand.Seed(time.Now().UnixNano())
	start := time.Now()
	realMain()
	fmt.Println(time.Since(start))
}

func realMain() {
	done := mixall(channels[0], channels[1:]...)
	for i := 0; i < NTHREADS; i++ {
		go startThread()
	}
	for i := 0; i < NTHREADS; i++ {
		<-done
	}
	fmt.Println("done")
}

func mixall(ch chan signal, rest ...chan signal) chan signal {
	for _, ch2 := range rest {
		ch = mix(ch, ch2)
	}
	return ch
}

func mix(ch1 chan signal, ch2 chan signal) chan signal {
	out := make(chan signal)
	go func() {
		for {
			select {
			case msg := <-ch1:
				out <- msg
			case msg := <-ch2:
				out <- msg
			}
		}
	}()
	return out
}

=>

done
9.3667769s

Итого разница максимум в 3 раза. Уже не так существенно.

korvin_ ★★★★★
()
Ответ на: комментарий от korvin_

Переписал Go-код на перебор каналов из channels:

package main

import (
	"fmt"
	"math/rand"
	"time"
)

type signal struct{}

const (
	NCHANNELS = 100
	NTHREADS  = 100000
)

var channels = makeChannels(NCHANNELS)

func pickChannel() chan signal {
	return channels[rand.Intn(NCHANNELS)]
}

func startThread() {
	time.Sleep(time.Millisecond * 100)
	pickChannel() <- signal{}
}

func makeChannels(n int) []chan signal {
	channels := make([]chan signal, n)
	for i := range channels {
		channels[i] = make(chan signal)
	}
	return channels
}

func main() {
	rand.Seed(time.Now().UnixNano())
	start := time.Now()
	realMain()
	fmt.Println(time.Since(start))
}

func realMain() {
	done := mixer()
	for i := 0; i < NTHREADS; i++ {
		go startThread()
	}
	for i := 0; i < NTHREADS; i++ {
		<-done
	}
	fmt.Println("done")
}

func mixer() chan signal {
	out := make(chan signal)
	go func() {
		i := 0
		n := NCHANNELS - 1
		for {
			select {
			case <-channels[i]:
				out <- signal{}
			default: // to make select non-blocking
			}
			if i == n {
				i = 0
			} else {
				i++
			}
		}
	}()
	return out
}

=>

done
1.2368222s

Как бы разница вернулась к примерно 30 раз. =)

korvin_ ★★★★★
()
Ответ на: комментарий от korvin_

Попробуешь реализовать такой же select

(define (mixer)
  (define out (make-channel))
  (define n (- NCHANNELS 1))
  (define select (apply choice-evt (vector->list channels)))
  (define (loop)
    (let loop ()
      (sync select)
      (channel-put out #t))
      (loop))
  (thread loop)
  out)

Только быстрей не становится.

monk ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.