Следующая страница > 1 < [2] [3]

Автор Сообщение

rv82

Members


Статус

46 сообщений
http://rv82.ya.ru
Где: Russia
Род занятий:
Возраст:

#5882   2012-03-14 18:51 GMT+3 часа(ов)      
Здравствуйте! Как известно, в составе Racket есть web-сервер. Также, не составит труда и самому написать многопоточный web-сервер. Вопрос в том, сможет ли такой сервер работать под большими нагрузками (сотни тысяч или даже миллионы подключений)? Или лучше для этого использовать связку Apache+Racket (как CGI)? Правда, если использовать последний вариант, то отпадают такие приятности, как continuations.

Говорят, Tomcat может обслуживать огромное количество подключений. Также, говорят, что на Node.js тоже можно писать тяжелонагруженные приложения. Но ведь в составе Racket тоже есть JIT-компилятор! А сам язык несравненно более удобен, чем Java/JavaScript.

megamanx

Members


Статус

307 сообщений

Где: Russia
Род занятий:
Возраст:

#5885   2012-03-15 00:04 GMT+3 часа(ов)      
Цитата
А сам язык несравненно более удобен, чем Java/JavaScript.

Угу, каэшна, он один есть истина и свет во тьме.
Цитата
сотни тысяч или даже миллионы подключений

Хуясе, а чё не миллиарды?
Цитата
Вопрос в том, сможет ли такой сервер работать под большими нагрузками

В одиночку нет, если сверху поставить кеширующий сервер (++архивирующий, а ещё статику вынести на отдельный сервер), то сможет.
I wish I'd made you angry earlier

misha

Moderators


Статус

1273 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#5888   2012-03-15 00:56 GMT+3 часа(ов)      
Цитата
Вопрос в том, сможет ли такой сервер работать под большими нагрузками
Конечно, но потребуется железо соответствующее текущим потребностям.
Цитата
сотни тысяч или даже миллионы подключений
Этого невозможно добиться без средств выравнивания нагрузки. Для мощного сервера-одиночки максимум это 10000 активных подключений, т.к. большее количество может привести к непредсказуемым последствиям (вплоть до отказа ОС).
Цитата
Или лучше для этого использовать связку Apache+Racket (как CGI)?
Еще хуже, т.к. будет тратится много ресурсов на запуск интерпретатора.

misha

Moderators


Статус

1273 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#5889   2012-03-15 01:23 GMT+3 часа(ов)      
Цитата
А сам язык несравненно более удобен, чем Java/JavaScript.
Писать Java/JavaScript не совсем корректно, ибо JavaScript - это самостоятельный язык (диалект ECMAScript) и к Java не имеет никакого отношения.
Кстати, хорошие интерпретаторы JavaScript по производительности не уступают лучшим интерпретаторам Лиспа.

megamanx

Members


Статус

307 сообщений

Где: Russia
Род занятий:
Возраст:

#5890   2012-03-15 02:30 GMT+3 часа(ов)      
Цитата
Конечно, но потребуется железо соответствующее текущим потребностям.

И что, смогёт? Это вопрос, это не издёвка. Сборщик мусора справится и способен подгребать под себя много памяти, система расчитана на многоядерные сервера, как ведёт себя при превышении лимита памяти?
I wish I'd made you angry earlier

misha

Moderators


Статус

1273 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#5892   2012-03-15 03:01 GMT+3 часа(ов)      
Цитата
Сборщик мусора справится и способен подгребать под себя много памяти, система расчитана на многоядерные сервера, как ведёт себя при превышении лимита памяти?
При нехватке памяти посылается исключение, которое можно перехватить и обработать.

rv82

Members


Статус

46 сообщений
http://rv82.ya.ru
Где: Russia
Род занятий:
Возраст:

#5896   2012-03-15 11:30 GMT+3 часа(ов)      
misha
Писать Java/JavaScript не совсем корректно, ибо JavaScript - это самостоятельный язык (диалект ECMAScript) и к Java не имеет никакого отношения.

Это я в курсе. Под словом Java подразумевал Java+Tomcat, а под JavaScript -- Node.js
misha
Кстати, хорошие интерпретаторы JavaScript по производительности не уступают лучшим интерпретаторам Лиспа.

А как соотносится производительность Racket с лучшими интерпретаторами Лиспа? Нашёл кое что по GNU Lightning, который используется в качестве jit-компилятора в Racket.
Цитата
megamanx :
Цитата
А сам язык несравненно более удобен, чем Java/JavaScript.

Угу, каэшна, он один есть истина и свет во тьме.

Точно! Если в JS ещё есть анонимные функции, то в жабе о них только говорят. О макросах и речи нет.
Цитата
megamanx :
Цитата
сотни тысяч или даже миллионы подключений

Хуясе, а чё не миллиарды?

А кто ж его знает! Просто одна контора хочет сделать один "социально значимый" проект. Поначалу больших нагрузок конечно же не будет. А потом, кто знает? Если сама контора до тех пор не сгинет.

megamanx

Members


Статус

307 сообщений

Где: Russia
Род занятий:
Возраст:

#5897   2012-03-15 13:54 GMT+3 часа(ов)      
то в жабе о них только говорят

Они есть, только требуют громоздкого кода... ну это к слову пришлось.
Горизонтальная расширяемость слабо связана с языком программирования, и даже не так сильно связана с базой данных. Слабое звено - это кеширование данных и, скажем, синхронизация работы на многих серверах. Важна также скорость разработки, и вот тут могу поспорить, что рекет хорош. Плюс - безопасность (о которой вообще ничего не известно для твоего фреймворка на рэкете), стабильность работы (о которой тоже ничего не известно, ведь, как говорил misha, стабильность не померить).
I wish I'd made you angry earlier

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#5898   2012-03-15 17:50 GMT+3 часа(ов)      
> Поначалу больших нагрузок конечно же не будет. А потом, кто знает?

Надо просто писать с учетом масштабируемости. Перестанет хватать производительности - купим еще пару серверов.

misha

Moderators


Статус

1273 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#5911   2012-03-20 21:15 GMT+3 часа(ов)      
rv82
А как соотносится производительность Racket с лучшими интерпретаторами Лиспа?
Я тестов не производил. Хотя с кем сравнивать? Реализации CL не поддерживают продолжения. А если среди Scheme, то Racket, пожалуй, самая быстрая реализация. Как вам уже известно, слабое место любой платформы с поддержкой продолжений - циклы.
megamanx
безопасность (о которой вообще ничего не известно для твоего фреймворка на рэкете), стабильность работы (о которой тоже ничего не известно, ведь, как говорил misha, стабильность не померить)
Безопасность - это слабое место любого фреймворка. А стабильностью и апач не может похвастать (у меня он падал и не раз). У него другое преимущество - комьюнити.

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#5915   2012-03-21 19:58 GMT+3 часа(ов)      
> Как вам уже известно, слабое место любой платформы с поддержкой продолжений - циклы.

А можно подробнее? Что не так с циклами?

> А если среди Scheme, то Racket, пожалуй, самая быстрая реализация.

А аналог веб-сервера racket на stateless-continuations вообще существует? Просто иначе continuation-based сервер не масштабируется. Никак вообще.

misha

Moderators


Статус

1273 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#5916   2012-03-21 23:03 GMT+3 часа(ов)      
Цитата
А можно подробнее? Что не так с циклами?
Проблема не в циклах, а в реализации vm. Т.е. требуется довольно сложная vm, но это проблема разработчиков. Кстати, в Racket циклы реализованы довольно хорошо, я бы даже сказал не хуже, чем у LispWorks и Allegro CL.
Цитата
А аналог веб-сервера racket на stateless-continuations вообще существует?
Что такое stateless-continuations?

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#5917   2012-03-21 23:58 GMT+3 часа(ов)      
> Проблема не в циклах, а в реализации vm.

Так какая именно сложность с циклами? Точнее - с хвостовой рекурсией?

> Что такое stateless-continuations?

stateless-servlets точнее. #lang web-server в racket. Осуществляется за счет cps-подобного преобразования кода, в результате продолжение можно сохранять у пользователя и передавать - например, в http-запросе, так что запрос может быть обработан любым сервером, а не только тем, куда пришел предыдущий запрос того же пользователя (как в случае обычных продолжений).

misha

Moderators


Статус

1273 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#5918   2012-03-22 01:06 GMT+3 часа(ов)      
Цитата
Так какая именно сложность с циклами? Точнее - с хвостовой рекурсией?
А зачем использовать хвостовой вызов (для локальной функции), когда можно использовать локальные переходы? Т.е. можно преобразовать локальные функции, которые не используются извне, в циклы.
Цитата
stateless-servlets точнее. #lang web-server в racket.
Они это называют serialized continuations.
Цитата
продолжение можно сохранять у пользователя и передавать - например, в http-запросе
Лучше не дарить хакеру такие подарки.
Цитата
так что запрос может быть обработан любым сервером, а не только тем, куда пришел предыдущий запрос того же пользователя (как в случае обычных продолжений).
Для этого обычно используют сервер БД.

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#5919   2012-03-22 04:11 GMT+3 часа(ов)      
Цитата
А зачем использовать хвостовой вызов (для локальной функции), когда можно использовать локальные переходы? Т.е. можно преобразовать локальные функции, которые не используются извне, в циклы.


Но зачем это делать-то? Хвостовой вызов в идеале - тот же самый переход. То есть сделав оптимизацию хвостовых вызовов преобразование в циклы получается искаробки. Но при чем тут продолжения все еще неясно

> Они это называют serialized continuations.

Ну так где-нибудь еще они есть? В какой-то схеме я слышал было serializable, но оно порождало жуткие тормоза.

> Лучше не дарить хакеру такие подарки.

Не понял. Вся информация со стороны клиента _в любом_ случае передается в http-запросе (если мы используем http конечно). Так что с точки зрения хакера разницы никакой.

Цитата
Для этого обычно используют сервер БД.

В этом случае запрос может быть обработан только тем сервером, у которого есть доступ к соответствующей базе (в которой лежит продолжение конкретного клиента) - то есть масштабируемость отсутствует. Как только мы подключаем балансировщик нагрузок - мы теряем возможность сохранять продолжение на сервере.

misha

Moderators


Статус

1273 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#5920   2012-03-22 18:04 GMT+3 часа(ов)      
Цитата
Но зачем это делать-то? Хвостовой вызов в идеале - тот же самый переход. То есть сделав оптимизацию хвостовых вызовов преобразование в циклы получается искаробки.
А как будет устроена эта vm? Большинство стековых машин вынуждены удалять предыдущий кадр стека. И тут главную роль играет механизм передачи аргументов и то, где размещается этот кадр стека. (Может подробнее?) Поэтому не стоит удивляться, что для .net хвостовой вызов в 8 раз медленнее обычного, т.е. единственная от него польза - экономия стековой памяти.
Цитата
Но при чем тут продолжения все еще неясно
Циклы должны быть реализованы максимально эффективно, но большинство разработчиков полагается на хвостовую рекурсию. А почему? Да, потому что простейшая реализация продолжений - cps. Поэтому в большинстве случаев кое-как реализовав оптимизацию хвостовых вызовов разработчики полагают, что этого вполне достаточно и далее не заморачиваются. Короче, разработчики стоят перед дилеммой - либо быстрые продолжения, либо быстрые циклы.

misha

Moderators


Статус

1273 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#5921   2012-03-22 18:32 GMT+3 часа(ов)      
Цитата
Ну так где-нибудь еще они есть? В какой-то схеме я слышал было serializable, но оно порождало жуткие тормоза.
Я этим не интересовался. Кстати, как быстра процедура десериализации?
Цитата
Не понял. Вся информация со стороны клиента _в любом_ случае передается в http-запросе (если мы используем http конечно). Так что с точки зрения хакера разницы никакой.
Анализ продолжения может дать полезную информацию о работе веб-приложения. Кстати, как будем проверять корректность продолжения? А то вдруг неприятель пошлет модифицированное продолжение, которое в поможет ему взломать приложение.
Цитата
В этом случае запрос может быть обработан только тем сервером, у которого есть доступ к соответствующей базе (в которой лежит продолжение конкретного клиента) - то есть масштабируемость отсутствует.
Допустим у всех серверов есть доступ к БД, хранящей информацию о активных сеансах.
Передавать пользователю всю информацию о сеансе крайне опасно. Поэтому пользователю передается обычно только зашифрованный идентификатор сеанса.

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#5922   2012-03-23 02:31 GMT+3 часа(ов)      
Цитата
А как будет устроена эта vm? Большинство стековых машин вынуждены удалять предыдущий кадр стека.

Так оптимизация хвостовой рекурсии в том и состоит, что кадр стека _не удаляется_. И новый, соответственно, тоже не создается.

Цитата
Поэтому не стоит удивляться

Конечо, не стоит, ведь задачи эффективной реализации хвостовых вызовов для разработчиков .net не стояло.

Цитата
Циклы должны быть реализованы максимально эффективно, но большинство разработчиков полагается на хвостовую рекурсию. А почему?

Очевидно, потому, что по производительности хвостовая рекурсия ничем не отличается от цикла (если оптимизация реализована правильно).

Цитата
Короче, разработчики стоят перед дилеммой - либо быстрые продолжения, либо быстрые циклы.

Непонятно. Выше мы выяснили, что циклы не нужны - ведь их можно заменить хвостовой рекурсией, которая не медленнее. но вопрос изначально стоял - какая связь между циклами и продолжениями? С какой стати эффективная реализация хвостовой рекурсии закрывает продолжения?

Цитата
Кстати, как быстра процедура десериализации?

Там же в #lang web-server продолжение как таковое не сериализуется. В месте захвата продолжения лифтится лямбда, имя лямбды с конкретными аргументами (которые представляют обычные числа, строки - любые типы ЯП) пакуется и куда-то уходит (в БД, пользователю, да хоть в памяти кешируется). При десереализации мы считываем эти данные, захватываем имя лямбды, десериализуем аргументы - продолжение готово. То есть никаких накладных расходов связанных с рантаймом тут нет - скорость десериализации ограничивается ровно тем, с какой скоростью мы можем получить данные и распарсить их.

Цитата
Анализ продолжения может дать полезную информацию о работе веб-приложения.

Еще раз - в любом веб-приложении вся та же информация все равно проходит в запросах. Продолжение должно содержать ту и только ту информацию, которая нужна для того, чтобы четко определить состояние. То есть ровно ту информацию, которая необходимо будет в строке http-запроса. Это не значит, конечно, что мы не можем напихать лишнего - но это уже другая проблема. Не надо пихать Да и с точки зрения оптимизации стоит ограничиваться необходимым. С точки зрения безопасности - можно и зашифровать как угодно.

Цитата
Допустим у всех серверов есть доступ к БД, хранящей информацию о активных сеансах.

Рано или поздно этот сервер таки не выдержит нагрузки, а второй уже не добавишь в силу особенностей архитектуры. Здесь, конечно, все зависит от того, где же будет этот момент "не выдерживания нагрузки" - но тут без тестов не скажешь, а их нет.

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#5923   2012-03-23 02:34 GMT+3 часа(ов)      
Цитата
Передавать пользователю всю информацию о сеансе крайне опасно.

Это ортогональный продолжениям вопрос. Такого рода информацию вполне можно отделять, так же как она отделяется в вебе. Кроме того state-less и state-full сервлеты можно смешивать - то есть делать так, что часть продолжения уходит пользователя, а часть - остается на сервере.

misha

Moderators


Статус

1273 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#5924   2012-03-23 03:15 GMT+3 часа(ов)      
Цитата
Так оптимизация хвостовой рекурсии в том и состоит, что кадр стека _не удаляется_. И новый, соответственно, тоже не создается.
Под удалением стекового кадра подразумевают преобразование верхнего кадра стека, по крайней мере, так зачастую реализован хвостовой вызов.Ты ведь хотел сказать написав "Но зачем это делать-то? Хвостовой вызов в идеале - тот же самый переход. То есть сделав оптимизацию хвостовых вызовов преобразование в циклы получается искаробки.", что существует какой-то способ оптимизации хвостовых вызовов, который я не знаю. Предложи как это сделать максимально эффективно без преобразования локальных функций.
Цитата
Очевидно, потому, что по производительности хвостовая рекурсия ничем не отличается от цикла (если оптимизация реализована правильно).
А мне не очевидно! Нужен полный анализ функции. Т.е. как я уже писал ранее, необходимо преобразование локальных функций в циклы, если это возможно. Это и есть полная оптимизация хвостовых вызовов.
Цитата
Непонятно. Выше мы выяснили, что циклы не нужны - ведь их можно заменить хвостовой рекурсией, которая не медленнее.
Это только твои утверждения, т.е. тебе это еще необходимо доказать.
Цитата
но вопрос изначально стоял - какая связь между циклами и продолжениями?
Повторяю: "Короче, разработчики стоят перед дилеммой - либо быстрые продолжения, либо быстрые циклы." Если тебе этого недостаточно, значит ты меня неправильно понял. Я не говорил о каком-то абсолюте, просто я еще не встречал реализации, где было бы все идеально реализовано.
Цитата
С какой стати эффективная реализация хвостовой рекурсии закрывает продолжения
Вот именно с какой? Не помню, чтобы я писал что-то подобное.

misha

Moderators


Статус

1273 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#5925   2012-03-23 03:44 GMT+3 часа(ов)      
Цитата
При десереализации мы считываем эти данные, захватываем имя лямбды, десериализуем аргументы - продолжение готово. То есть никаких накладных расходов связанных с рантаймом тут нет - скорость десериализации ограничивается ровно тем, с какой скоростью мы можем получить данные и распарсить их.
Так какова скорость десериализации? А то судя по тому что ты написал, она довольно велика. Т.е. даже по скорости они не выигрывают.
Цитата
Еще раз - в любом веб-приложении вся та же информация все равно проходит в запросах. Продолжение должно содержать ту и только ту информацию, которая нужна для того, чтобы четко определить состояние. То есть ровно ту информацию, которая необходимо будет в строке http-запроса.
А чем это лучше классики "http://www.lisp.ru/forums.php?m=posts&q=949&n=last#bottom"? Наверное содержит кучу скобок
Цитата
С точки зрения безопасности - можно и зашифровать как угодно.
Это и без продолжений возможно.
Цитата
Рано или поздно этот сервер таки не выдержит нагрузки, а второй уже не добавишь в силу особенностей архитектуры.
А кто сказал, что он один? Идентификатор сеанса может содержать идентификатор сервера на котором хранится состояние сеанса.

отредактировал(а) misha: 2012-03-23 04:00 GMT+3 часа(ов)

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#5926   2012-03-23 11:48 GMT+3 часа(ов)      
Цитата
что существует какой-то способ оптимизации хвостовых вызовов, который я не знаю.

Стандартный способ хвосторекурсивной оптимизации. В качестве нового фрейма используется текущий фрейм (то есть на работу с фреймами вообще время не тратится), а хвосто-рекурсивный вызов превращается в в безусловный переход.

Цитата
Т.е. как я уже писал ранее, необходимо преобразование локальных функций в циклы, если это возможно.

Да не надо ничего преобразовывать, если оптимизация хвостовой рекурсии есть - оно _уже_ преобразовано. Ф-я после оптимизации хвостовой рекурсии выглядит в точности как цикл.

Цитата
Это только твои утверждения, т.е. тебе это еще необходимо доказать.

Да это уже изучено и доказано стопицот раз. hint: циклов в scheme нету именно из-за того, что после оптимизации хвосторекурсивные вызовы как раз в них и превращаются. То есть никаких потерь скорости.

Цитата
Вот именно с какой? Не помню, чтобы я писал что-то подобное.

Как не писал? Вот же:
"Короче, разработчики стоят перед дилеммой - либо быстрые продолжения, либо быстрые циклы."

ну я и повторяю вопрос - почему эффективная реализация хвостовой рекурсии исключает эффективную реализацию продолжений?

Цитата
Так какова скорость десериализации?

Я, по-моему, вполне четко на этот вопрос ответил.

Цитата
А то судя по тому что ты написал, она довольно велика.

Ну да. Ведь никаких накладных расходов нет (которые бывают в случае обычных продолжений).

Цитата
Т.е. даже по скорости они не выигрывают.

А они и не должны. Зачем? не будет хватать скорости - ставим еще сервер. В этом суть.

Цитата
А чем это лучше классики

Ну тем, чем лучше классики любой continuation-based сервер
Прямой, интуитивно-понятный control-flow вместо реализации конечного автомата руками.

Цитата
Это и без продолжений возможно.


Конечно. Речь шла о том, что продолжения тоже можно сделать безопасными. Как я уже вышел сказал - у продолжений лишь одно преимущество: "прямой, интуитивно-понятный control-flow вместо реализации конечного автомата руками.", остальное - недостатки. И их много.

Цитата
А кто сказал, что он один? Идентификатор сеанса может содержать идентификатор сервера на котором хранится состояние сеанса.

Так нагрузку балансировать ты не сможешь. В этом случае впонле реальна ситуация, при которой первый сервер падает от нагрузки, а второй загружен едва ли на 10%...

misha

Moderators


Статус

1273 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#5927   2012-03-23 22:31 GMT+3 часа(ов)      
Цитата
Стандартный способ хвосторекурсивной оптимизации. В качестве нового фрейма используется текущий фрейм (то есть на работу с фреймами вообще время не тратится), а хвосто-рекурсивный вызов превращается в в безусловный переход.
Ты отвечаешь не на тот вопрос. Я спрашивал об оптимизации хвостового вызова.

Зачем ты писал "в качестве нового фрейма используется текущий фрейм", если после хвосторекурсивной оптимизации будет создана функция, содержащая цикл. Т.е. после её вызова будет создан новый фрейм, поэтому если подобные функции имеют незначительный "размер", то их желательно инлайнить.
(define (tc-test0 i)
(if (< i 100000000) (tc-test1 (add1 i)) i))
 
(define (tc-test1 i)
(if (< i 100000000) (tc-test0 (add1 i)) i))
 
(displayln 'tc-test)
(time (tc-test0 0))
;(set! tc-test0 #f)
;(set! tc-test1 #f)
 
(define (tr-test0 i)
(if (< i 100000000) (tr-test0 (add1 i)) i))
 
(displayln 'tr-test0)
(time (tr-test0 0))
;(set! tr-test0 #f)
 
(define (bad-tr-test0 i t1 t2 t3 t4)
(if (< i 100000000) (bad-tr-test0 (add1 i) t1 t2 t3 t4) i))
 
(displayln 'bad-tr-test0)
(time (bad-tr-test0 0 1 2 3 4))
;(set! bad-tr-test0 #f)
 
(define (bad-tr-test1 i . r)
(if (< i 100000000) (bad-tr-test1 (add1 i) 1 2 3 4) i))
 
(displayln 'bad-tr-test1)
(time (bad-tr-test1 0))

Результаты
tc-test
cpu time: 1969 real time: 2016 gc time: 0
100000000
tr-test0
cpu time: 484 real time: 484 gc time: 0
100000000
bad-tr-test0
cpu time: 578 real time: 578 gc time: 0
100000000
bad-tr-test1
cpu time: 2641 real time: 2719 gc time: 330
100000000
Попробуй объяснить результаты. Чтобы отключить оптимизации требующие предпросмотра раскомментируй сеты. Функции с префиксом tr и bad-tr даны для сравнения, но их также можно использовать, если раскомментировать их сеты, т.к. они отключат оптимизацию хвостовой рекурсии.
Цитата
Да не надо ничего преобразовывать, если оптимизация хвостовой рекурсии есть - оно _уже_ преобразовано. Ф-я после оптимизации хвостовой рекурсии выглядит в точности как цикл.
Функция после оптимизации хвостовой рекурсии выглядит как функция, содержащая цикл. Если, конечно, её компилятор не использует как инлайн фунцию. Да и это ты описываешь полную оптимизацию хвостовой рекурсии, т.к. частичная не предполагает преобразование кода функции в цикл, т.е. она сродни оптимизации хвостовых вызовов. Кстати, подобная оптимизации хвостовой рекурсии для Лиспа требует предпросмотра (анализа) всего кода программы. Так о чем ты думал, когда писал: "То есть сделав оптимизацию хвостовых вызовов преобразование в циклы получается искаробки."? Оптимизация хвостовых вызовов обычно подразумевает просто замена call на его эквивалент, назовем его tail-call. Поэтому любой хвостовой вызов можно оптимизировать, а не только рекурсивный.
Цитата
циклов в scheme нету именно из-за того, что после оптимизации хвосторекурсивные вызовы как раз в них и превращаются. То есть никаких потерь скорости.
Главное - не путать с инлайнингом, который частенько имеет место.
(define (tr-test0 i)
(if (< i 100000000) (tr-test0 (add1 i)) i))
 
(displayln 'tr-test0)
(time (tr-test0 0)) ; инлайнинг
;(set! tr-test0 #f) ; без него
С инлайнингом
tr-test0
cpu time: 484 real time: 484 gc time: 0
100000000
Без инлайнинга
tr-test0
cpu time: 1438 real time: 1453 gc time: 0
100000000
Если бы я где-то использовал tr-test0 в качестве значения, то создалась просто бы функция содержащая цикл. Вообще сама задача оптимизации хвостовой рекурсии требует сложного анализа кода программы, поэтому определить требуется ли оптимизация или нет довольно сложно. Например, добавление сета запрещает оптимизацию, а в данном случае сет необходимо проигнорировать.

отредактировал(а) misha: 2012-03-24 03:49 GMT+3 часа(ов)

misha

Moderators


Статус

1273 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#5928   2012-03-23 23:27 GMT+3 часа(ов)      
Цитата
ну я и повторяю вопрос - почему эффективная реализация хвостовой рекурсии исключает эффективную реализацию продолжений?
Не хвостовой рекурсии, а вызовов функций вообще Эффективная реализация хвостовой рекурсии, а это для Лиспа вообще возможно? А у меня, кстати, почему-то показатели для оптимизированных функций (хвостовая рекурсия) Racket-ом сродни их не хвостовым аналогам из .net, т.е. циклы Racket-а довольно "прожорливые".
Цитата
Я, по-моему, вполне четко на этот вопрос ответил.
Я хотел увидеть цифры. Хотя, сейчас мне это уже не важно.
Цитата
Ведь никаких накладных расходов нет (которые бывают в случае обычных продолжений).
Просто я считал, что они имеют специальную структуру для облегчения распаковки.
Цитата
А они и не должны. Зачем? не будет хватать скорости - ставим еще сервер. В этом суть.
Я думал, что это передовая технология
Цитата
Прямой, интуитивно-понятный control-flow вместо реализации конечного автомата руками.
А причем здесь конечный автомат? Просто разработчики захотели добавить скобок
Цитата
Так нагрузку балансировать ты не сможешь. В этом случае впонле реальна ситуация, при которой первый сервер падает от нагрузки, а второй загружен едва ли на 10%...
Сервер БД может обработать только определенное количество клиентов (рассчитать это число заранее). Перед выдачей идентификатора необходимо определить менее загруженный сервер. Желательно, чтобы было разделение на сервера работающие с авторизованными клиентами и анонимными. Необходимо ограничить количество идентификаторов выдаваемых для одного IP. Каждому клиенту свой идентификатор (привязан к IP), необработанные запросы ложатся в стек, принадлежащий этому идентификатору. Если стек переполнен, то вероятна DoS-атака, поэтому необходимо принять соответствующие меры. В принципе, все можно рассчитать заранее.
Кстати, не забывай, что я говорил об информации о сеансе (состояние сеанса), которая обычно содержит только важные сведения, такие как IP, id пользователя (если авторизован) и текущие привилегии пользователя, и возможно др. А остальное, например, содержание его корзины с покупками, можно хранить на стороне клиента.

отредактировал(а) misha: 2012-03-24 04:17 GMT+3 часа(ов)

kreol

Members


Статус

87 сообщений

Где: Ukraine Днепропетровск
Род занятий: студент
Возраст: 24

#5929   2012-03-24 19:39 GMT+3 часа(ов)      
мдааа. смотрю на топик что-то жутко умное и ничего не понятное(((
Что такое инлан функция? и что значит заинлайнить?

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#5930   2012-03-25 14:41 GMT+3 часа(ов)      
Цитата
Т.е. после её вызова будет создан новый фрейм

Новый фрейм создается только при первом вызове (на первой итерации цикла). Дальше никаких фреймов не создается.

Цитата
Попробуй объяснить результаты.

А что странного в этих результатах?

Цитата
Функция после оптимизации хвостовой рекурсии выглядит как функция, содержащая цикл.

Ну да. Так какие проблемы с этим?

Цитата
т.к. частичная не предполагает преобразование кода функции в цикл

да нету никакого преобразования функции цикл. просто _так выходит_ (чисто случайно), что после хвосторекурсивной оптимизации результат выглядит как цикл.

Цитата
Кстати, подобная оптимизации хвостовой рекурсии для Лиспа требует предпросмотра (анализа) всего кода программы.


С чего вдруг?

Цитата
Оптимизация хвостовых вызовов обычно подразумевает просто замена call на его эквивалент, назовем его tail-call. Поэтому любой хвостовой вызов можно оптимизировать, а не только рекурсивный.

Да. Просто кроме tail-call обычно рассматривается еще и рекурсивный tail-call, в случае которого можно оптимизировать вызов еще лучше.

Цитата
Например, добавление сета запрещает оптимизацию

Верно, если мы добавим сет, то уже не можем гарантировать, что вызов, собственно, рекурсивный.

misha

Moderators


Статус

1273 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#5931   2012-03-25 14:42 GMT+3 часа(ов)      
2 Kergan
Я думаю, необходимо создать отдельный тред.

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#5932   2012-03-25 14:52 GMT+3 часа(ов)      
Цитата
Эффективная реализация хвостовой рекурсии, а это для Лиспа вообще возможно?

а какие здесь подводные камни?

Цитата
Racket-ом сродни их не хвостовым аналогам из .net, т.е. циклы Racket-а довольно "прожорливые".

Весьма поспешно заявлять, что дело тут в прожорливых циклах - .net намного шустрее racket, т.к. и типизация статическая, и ВМ менее фичастая, и jit гораздо бодрее (в racket вообще gnu lightning, который не особенно эффективный по сравнению с, например, тем же llvm код генерирует).

Цитата
Просто я считал, что они имеют специальную структуру для облегчения распаковки.

Ну конечно она специальная. Вот на счет того как она облегчает распаковка (и как вообще даже теоретически структура может облегчить распаковку) - я не в курсе

Цитата
Я думал, что это передовая технология

Передовая в том, что масштабируема. В отличии от

Цитата
А причем здесь конечный автомат?

При том, что любое веб-приложение, в силу особенностей http-протокола, является реализацией конечного автомата

Цитата
Перед выдачей идентификатора необходимо определить менее загруженный сервер.

Так в дальнейшем нагрузка вполне может измениться, а идентификатор _уже_ выдан. Мы заранее не сможем сказать какова нагрузка будет по данному идентификатору.

misha

Moderators


Статус

1273 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#6007   2012-04-20 16:13 GMT+3 часа(ов)      
Цитата
Новый фрейм создается только при первом вызове (на первой итерации цикла). Дальше никаких фреймов не создается.
Это и ежу понятно
Цитата
А что странного в этих результатах?
По ним можно приближенно судить о деталях реализации хвостовых вызовов в данной VM. Возможность применения конкретной оптимизации зависит от устройства VM, поэтому меня больше интересуют не оптимизации, а сама VM, т.е. как реализован фрейм стека, где хранятся аргументы функции, и т.д.
Иными словами, предложи устройство VM, в которой хвостовой вызов будет реализован максимально эффективно.
Цитата
да нету никакого преобразования функции цикл. просто _так выходит_ (чисто случайно), что после хвосторекурсивной оптимизации результат выглядит как цикл.
Объясни понятнее, что ты хотел этим сказать.
Цитата
С чего вдруг?
Функцию можно переопределить.
Цитата
Да. Просто кроме tail-call обычно рассматривается еще и рекурсивный tail-call, в случае которого можно оптимизировать вызов еще лучше.
Можно более детально? А то я впервые слышу про "рекурсивный tail-call", т.к. обычно вставляется обработка подобной ситуации. Т.е. вставляется проверка на рекурсивный вызов, и если он есть, то просто переопределяем параметры (присваиваем новые значения) и совершаем переход на начало. Иначе происходит tail-call.

misha

Moderators


Статус

1273 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#6008   2012-04-20 17:22 GMT+3 часа(ов)      
Цитата
а какие здесь подводные камни?
Требуется более продвинутый declaim.
Цитата
.net намного шустрее racket, т.к. и типизация статическая
Я использовал короткие целые, поэтому не было никакой распаковки (unboxing).
Цитата
в racket вообще gnu lightning, который не особенно эффективный по сравнению с, например, тем же llvm код генерирует
Т.к. llvm на оптимизацию кода тратит много времени, поэтому обычно отключают большинство оптимизаций кода.
Цитата
Вот на счет того как она облегчает распаковка (и как вообще даже теоретически структура может облегчить распаковку) - я не в курсе
Сжатые данные всегда структурированы, а иначе как будем производить распаковку?
Цитата
Передовая в том, что масштабируема. В отличии от
Разве "старые" технологии запрещают хранить данные на стороне клиента? Вот только все это требует шифрования, поэтому возрастает нагрузка на сервер. Т.к. обычно чем лучше алгоритм, тем дольше расшифровка данных.
Цитата
При том, что любое веб-приложение, в силу особенностей http-протокола, является реализацией конечного автомата
Большинство приложений работающих с данными является реализациями конечного автомата. Применение продолжений всего-лишь несколько упрощает его вид, и не более того.
Цитата
Так в дальнейшем нагрузка вполне может измениться, а идентификатор _уже_ выдан. Мы заранее не сможем сказать какова нагрузка будет по данному идентификатору.
Речь идет о состоянии сеанса, поэтому мы всегда можем спрогнозировать максимально возможную нагрузку созданную одним пользователем. И если это значение превышено, то мы возможно имеем дело с DoS-атакой, поэтому необходимо принять соответствующие меры(например, временный бан ip), и тем самым избежать отказа в обслуживании. Если бы этот подход был бы таким уж плохим, то большинство веб-серверов не раздавало бы идентификаторы сеанса.
А как ты предлагаешь бороться с DDoS-атаками?

отредактировал(а) misha: 2012-04-20 17:31 GMT+3 часа(ов)


Онлайн :

0 пользователь(ей), 14 гость(ей) :




Реклама на сайте: