Не буду писать многабукаф - просто скажите, сколько (по времени в секундах) в Scheme выполняется данный кот:
(define (divs n)
(define (go i a)
(cond ((> (* i i) n) a)
((= (* i i) n) (+1 a))
((=0 (modulo n i)) (go (+1 i) (+2 a)))
(else (go (+1 i) a))))
(go10))
(define (task n k)
(cond ((>=500 (divs k)) (task (+1 n) (+ k n 1))) (else k)))
(display (task11))
Я пробовал несколько онлайн вычисляторов, и время выполнения различается на порядки. Где-то указывают реализацию (chiken / guile), где-то нет. Здесь https://repl.it/languages/scheme какое-то неприличное время выполняется, здесь https://www.tutorialspoint.com/execute_scheme_online.php весьма неплохо (относительно остальных), на Ideone и Rextester промежуточные показатели... Я в растерянности - где правда?
Мерить время выполения на онлайн-выполняторах глупое занятие. Там настройки выкручены чтоб бы не грузить сервер. Guile как аналог python/ruby-ей никогда скоростью не славился. Chicken-компилятор работает быстро поверх C, что врдяли возможно в онлайн на сервере. А интерпретатор произвольного кода у него не сильно быстрый по идее.
По ссылке, где выполняется бесконечно долго, прочитал
BiwaScheme Interpreter version 0.6.4
Copyright (C) 2007-2014 Yutaka HARA and the BiwaScheme team
так что там действительно кто во что горазд... Можете посоветовать оптимальный вариант скачать/установить локально? В принципе в варианте по второй ссылке стартового поста мне более-менее нравится скорость.
Можете посоветовать оптимальный вариант скачать/установить локально?
Если ты никогда такого не ставил, то виртуалку с попсовым линуксом и поставить тот же chicken из реп. Хотя все вручную тоже должно работать. Хотя это все таки схемщиков надо спрашивать, я все таки лиспер :)
Такое сравнение не имеет смысла. И абсолютное значение времени выполнения тоже не имеет смысла. Реализуй один и тот же алгоритм на двух языках и тогда ты можешь определить относительную производительность двух реализаций этих языков на подобных задачах.
Ivana, мой пост в этой теме имеет смысл, потому что говорит, что вопрос заданный в теме не имеет смысла и предлагает на выбор несколько вопросов, ответы на которые сообщат Вам более осмысленную информацию.
Уточню. В вопросе «сколько работает этот код» нет смысла, потому что на это влияет слишком много незафиксированных переменных. Смысл есть в вопросах:
1. Насколько дольше выполняется этот код в одних реализациях Scheme, чем в других при одинаковом железе. На этот вопрос уже ответил Puzan в, объективно, самом осмысленном комментарии в этом треде.
2. Насколько дольше выполняется этот код в реализациях Scheme в сравнении с аналогичным кодом на других языках на одинаковом железе.
Ivana, нет, продолжаю наполнять тему осмысленными постами, а вы продолжаете утверждать, что мои осмысленные посты бессмысленны.
UPD: На самом деле, да. Мой пост действительно был бессмысленным, потому что к тому моменту как я его сделал Puzan уже дал ответ на более осмысленный вопрос, чем тот бессмысленный, который Вы задали в ОП. :)
Дело в том, что мне не нужна аутентичная стандартная в полной мере схема. Я просто написал три реализации своего схемоподобного по синтаксису и семантике языка, интерпретаторы. Но поскольку особой оптимизации не делал, скорость выполнения оставляет желать - например кот из стартового поста на паре реализаций выполняется 40 секунд и 3 минуты 50 секунд соответственно. Желая получить возможность убыстрить исполнение, я подумал, что чем самостоятельно пытаться курить JIT или статическую оптимизирующую компиляцию, проще будет попробовать транслировать котов на моем диалекте в какой-нибудь готовый промышленный язык с оптимизациями на борту. Попробовал в Java, но ниасилил победить стековерфлоу. Потом меня осенило, что если не брать спецвозможностей моего диалекта, определяемых платформой реализации, то он синтаксически и семантически похож на схему - почему бы не транслировать в какой-нибудь из ее диалектов? Поскольку локально ничего не стояло, полез в инет на онлайн-РЕПЛы проверять эффективность, удивился результатам и создал эту тему. В результате (спасибо осмысленно пишущим участникам) выбрал Racket (я на винде, измучен мышовыми гуями, да и скорость на примере одна из лучших), и сейчас с интересом узнаю, что можно не только учить мой диалект конвертировать кот в синтаксис схемы (обильно досыпая скобок при этом, что имхо не способствует читабельности и понимабельности), но и написать на Racket реализацию своего диалекта, т.к. в нем присутствуют бортовые возможности для этого - это приятный бонус к скорости, удобному гуевому РЕПЛу, хорошей документации и т.п.
Вот, вкратце, что я хотел сказать о моих целях и мотивации.
Racket со многих сторон хорош. Накостылил на своем языке транслятор его же кода в Racket, альфа-версию, но вполне применимую. Например, после тривиальной доработки напильником получается вот такой ракетный кот, который вполне себе работает
#lang racket
(define (noelem x l) (cond ((null? l) #t) ((equal? x (car l)) #f) (else (noelem x (cdr l)))))
(define (take n l) (cond ((null? l) nil) ((> n 0) (cons (car l) (take (- n 1) (cdr l)))) (else nil)))
(define (drop n l) (cond ((null? l) nil) ((> n 0) (drop (- n 1) (cdr l))) (else l)))
(define nil '())
(begin (display"ЗАДАЧА - решение судоку, реализация поиска в глубину:") (display"\n"))
(define field (quote (009301800000000030200070009100209004004080200800706001900010005020000070005602400)))
(define (showField f) (define (go f) (cond ((null? f) "") (else (string-append (foldl (lambda (x a) (string-append a (number->string x) " ")) "" (take9 f)) "\n" (go (drop9 f)))))) (cond ((null? f) "Нет решений") (else (go f))))
(begin (display"Стартовое поле:") (display"\n")) (display (showField field))
(define (steps field)
(define (step-vars i) (begin (define r (/ i 9)) (define c (modulo i 9)) (define rs0 (*3 (/ r 3))) (define cs0 (*3 (/ c 3)))) (define (squ-row n) (take3 (drop (+ cs0 (*9 (+ rs0 n))) field))) (define (sieve-nth l a) (cond ((null? l) a) (else (sieve-nth (drop9 l) (cons (car l) a))))) (foldl (lambda (l a) (filter (lambda (x) (noelem x l)) a)) (quote (123456789)) (list (squ-row0) (squ-row1) (sieve-nth (drop c field) (squ-row2)) (take9 (drop (*9 r) field)) nil)))
(define (rep-by-ind i e l) (cond ((null? l) nil) ((=0 i) (cons e (cdr l))) (else (cons (car l) (rep-by-ind (- i 1) e (cdr l))))))
(define (go i min-i min-step-counts min-step-vars f)
(cond ((null? f) (cond ((= min-step-counts 100) (cons field nil))
((= min-step-counts 0) nil)
(else (map (lambda (v) (rep-by-ind min-i v field)) min-step-vars))))
((=0 (car f)) (begin (define i-step-vars (step-vars i))
(define i-step-counts (length i-step-vars))
(cond ((< i-step-counts min-step-counts)
(go (+ i 1) i i-step-counts i-step-vars (cdr f)))
(else (go (+ i 1) min-i min-step-counts min-step-vars (cdr f))))))
(else (go (+ i 1) min-i min-step-counts min-step-vars (cdr f)))))
(go001000 field))
(define (solve-depth field)
(define (go f) (define vars (steps f)) (cond ((noelem0 f) f) ((null? vars) nil) (else (foldl (lambda (x a) (cond ((null? a) (go x)) (else a))) nil vars))))
(go field))
(begin (display"Решение поиском в глубину:") (display"\n"))
(begin (display (showField (solve-depth field))) (display"\n"))
Конечно можно придраться, что одни define и никаких let, что (display «\n») а не (newline) и т.п. Но для экспресс-варианта имхо катит.