LINUX.ORG.RU

Оптимизация в питоне?

 


1

3

Где про это почитать можно. С самых простых вещей, что это такое вообще и зачем и как ее делают. И чем это отличается от рефакторинга?



Последнее исправление: cetjs2 (всего исправлений: 1)
Ответ на: комментарий от vertexua

Ну так Java действительно прощает крайне неаккуратное обращение с кодом. Всякие фортеля вроде, сделать цикл от нуля до миллиарда и без слипов выплёвывать оттуда мутабельные объекты размером с кулак. Может так магически выйдет, что всё это можно будет почикать эскейп анализом и сказать, что раз данные нигде не используются, то и создавать мы их не будем. Или хотя бы растворим скаляризацией. Или умный GC поймёт что происходит треш и угар, и начнёт расстреливать сталинским методом - группируя в огромные блоки мусора и расстреливая за одну операцию блок целиком, и всё это параллельно чтобы всё не встало колом, даже несмотря на отсутствие слипов в говнокоде (А на C++ такой расстрел ещё попробуй напиши самостоятельно). Я раньше как раз любил показывать синтетический тест, на котором переход на JIT из Graal ускоряет говнокод на Scala в стопятьсот раз просто по факту агрессивного эскейп анализа.

И то же самое в статике, например в плане юнитов компиляции. В обычном приложении на Java никто не скупится на классы. Любая сущность - это класс. В библиотеке Apache Camel как сейчас помню около 7000 классов - и это была одна из более сотни зависимостей того проекта. А потом и мы, обычные говнокодеры, за два месяца написали в этом проекте пару тысяч классов. Я хорошо это помню, на эту тему был обширный срач в моем фейсбуке. Но в джаве это не проблема, у всех всё просто работает.

Люди привыкают, к хорошему. И тут C++, в котором в принципе ты тоже можешь сделать приложение на миллион классов. И всё встанет колом. И придётся мараться обо всякое говнище, мутить странные юнити билды, просаживать перформанс невключением LTO, которое на достаточно большом объеме кода может работать миллион лет, и вообще. Условно говоря, браузер Chromium на моём компе (Skylake, 16 Gb RAM, самсунговский m.2 pcie ssd) полностью собирается целую ночь, и после сборки занимает.... я не могу посмотрть сколько гигабайтов, потому что считаться будет минут десять. Скажем так, удивлюсь, если меньше 50 гигабайт. Такого НИКОГДА не бывает даже с самыми жирными джава приложениями. Джава приложения понимают, что большая часть этого кода не нужна, и компилируют только самую нужную часть прямо в рантайме.

И да, всё это - огромная поддержка для меня как разработчика. Я понимаю, что могу сконцентрироваться на смысле решаемой задачи, а не на мелочах вроде перформанса.

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 2)
Ответ на: комментарий от anonymous

«красивый» код - это удел или зеленых или очень давно остановившихся в развитии недопрограммистов.

Ты ведь знаешь, кто такой Дядя Боб, верно? Будешь спорить с его резюме?

https://blog.cleancoder.com/uncle-bob/2019/08/22/WhyClojure.html

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

Если это тот дядя Боб, который топит за юнит-тестирование, то это обыкновенный мудак и никакое его резюме я даже читать не собираюсь (ну как минимум потому, что ни достижения человека, ни его резюме никогда не могут служить средством оценки здравости идей, отсутствия заблуждений или достоверности заялений).

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

Кстати идея «чистого» кода (как и пресловутое «качество» кода) - точно так же удел или несозревших (профессионально, «творчески» как угодно, в целом незрелых) или просто идиотов.

anonymous
()
Ответ на: комментарий от stevejobs

Можно писать джаву, такую же быструю, как C/C++, но она будет дичайше некрасивая.

Можно пример?

anonymous
()
Ответ на: комментарий от stevejobs

Т.е. если скомпилировать в натив JS то бyдет медленнее V8? А то может зря я собрался писать компилирyемyю нодy.

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

Ну для начала, я не думаю, что «настоящий JS» вообще можно скомпилировать в натив ;) У тебя будет, скорей всего, какая-то часть интерпретируемая и какая-то компилируемая. Просто по стандарту языка.

Для Java в GraalVM (SVM, Native-Image) просто сказали, что мы не сможем так писать на «настоящей Java», мы будем писать на джава-подобном языке с огромными ограничениями. И это камень преткновения, потому что если ты разрабатываешь на обычной Java и только для прода компилируешь под Native-Image в экзешник, то вступают в силу все эти ограничения, и зачастую людям приходится переписывать свой код, потому что они недостаточно хорошо держали в голове эти ограничения.

Что касается перформанса, то тут трудно сказать. Скорей всего, компилируемая нода будет медленней тупо потому, что ты пишешь ее в 1 рыло, а V8 пишет толпа очень квалифицированных программистов гугла, которые могут чуть ли не на ассемблере вылизывать её для конкретных случаев. Грубо говоря, в GraalVM тоже есть свой интерпретатор JS, и хотя он тоже очень неплох, в некоторых тестах он сливает V8 подчистую, например в тестах на регулярные выражения, там в V8 прямо произведение искусства понаписано.

Если же представить, что допустим вы пишете одинаковыми силами, то тут уже возникают теоретические вопросы, да. Например гляди, в V8 никогда не JIT-компилируются методы, у которых больше 3 параметров в функции, или больше пяти, уже не помню. Если хочешь сделать функцию, которая тормозит на V8 - просто сделай ей побольше параметров, JIT ее не тронет и она будет там как кость в горле. А не трогает он её именно из-за того, что для специализации и частичной компиляции метода под разные параметры нужно потратить слишком много кодкэша. Условно говоря, метод которому на вход постоянно приходят три инта, и метод которому на вход приходит три строки - должны компилироваться радикально разными способами. Теперь представь метод, у которого постоянно меняются типы входных параметров - иногда это инты, а иногда строки, а иногда что-то ещё. Тебе нужно перебрать и скомпилировать все возможные частичные спецализации. Это тупо комбинаторный взрыв, если делать по-простому. (По сложному сделано в фреймворке Truffle из GraalVM, на котором написан Graal.js, он справится и с более чем тремя, но там очень сложный способ, я его не объясню в этом комментарии). Чтобы не иметь с этим дела, чуваки из Гугла просто не компилируют ничего, где много параметров. Для маленького количества параметров они начинают выводить «временные типы» скорей всего, я бы так сделал, но это надо уже копаться в доках на TurboFan/Ignition чтобы понять как по-настоящему. Но вот проблема, методы с большим количеством параметров и методы с переменными типами в JS - это норма, так все делают. И тебе придётся компилировать их по-честному. И либо тебе придётся брать сразу самый обобщённый вариант (и это будет очевидно всегда медленней, чем частичная специализация - два произвольных объекта сильно сложней сложить, чем два инта), либо устраивать комбинаторный взрыв и компилировать вечно. В целом, твой «компилируемый V8» будет на таких методах работать всегда менее удовлетворительно для пользователя, чем JIT по методам с короткой сигнатурой.

Короче, это можно очень долго теоретизировать, попробуй написать что-нибудь сам и посмотреть на результаты, погоняв какие-то синтетические тесты вроде моего [Carbon](https://github.com/graalvm-community/graalvm-carbon) (это гугловый Octane, перепакованный в один файл, чтобы легко запускать на Ноде). Кажется, это хорошая тема для мастерского тезиса или что-то такое, если ты найдёшь какую-то достаточно интересную тему чтобы проверить. Если вдруг будешь такое делать, то очень советую читнуть работы по GraalVM за авторством Вертингера и ко, он начинался точно так же, они делали универсальный фреймворк для интерпретации на примере JS движка.

Олсо, в языке-Java таких проблем нет, т.к. типы настоящие, фиксированные. Более фиксированные типы есть в TypeScript, и у нас на следующей HolyJS [будет докладчик](https://holyjs-moscow.ru/2019/msk/talks/4y3sifyqmh036vhhecbqfr/), который собирается рассказать про компиляцию TS, но у меня есть заранее предположения, что там будет: если TS-компилятор должен обрабатывать вообще весь язык, а не closed world мира TS, то мы приходим к обобщенной программе на JS, для которой AOT-компиляция не имеет смысла.

На самом деле, весь этот вопрос можно решить тем, чтобы компилировать не весь JS целиком, а только какое-то особое подмножество, которое будет стабильно генерить одинаковые временные типы для огарниченного прямо в компиляторе количества параметров (указал больше пяти - это ошибка компиляции). Но это тема для совершенно другого ответа :)

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 1)
Ответ на: комментарий от vertexua

Это ты смотри в выступлениях своего кумира боба, там много смехотворных идей, например «дисциплина» вполне подойдет.

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

Боб твой кумир больше чем мой. По крайней меры ты, в отличие от меня, похоже знаешь кто это

vertexua ★★★★★
()

О, тролля-ТС забанили. Значит у него есть шанс закончить свой говновуз и стать программистом.

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

тролля-ТС забанили

Смешная причина забана кстати. Теперь то конечно она будет меньше флудить анонимусом. Л - логика.

no-such-file ★★★★★
()
Ответ на: комментарий от vertexua

А дело вот в чём.

Вы можете просмотреть на ЛОРе мой лог всех моих мыслей.

Это кладезь разума, поскольку я умный.

Так вот.

Пятнадцать лет назад хипстеры на ЛОРе хайпили Моню и Шарпея.

Я постигал Великий Путь Java.

Десять лет назад хипстеры на ЛОРе хайпили Эрланг, Хацкель, Камл.

Я постигал Великий Путь Java.

Пять лет назад хипстеры на ЛОРе хайпили Rust.

Я постигал Великий Путь Java.

Сейчас хипстеры на ЛОРе хайпят Go.

Я постигаю Великий Путь Java.

https://www.tiobe.com/tiobe-index/

https://www.tiobe.com/tiobe-index/java/

Highest Position (since 2001): #1 in Oct 2019

(C) TIOBE Index for October 2019

Ибо я очень умный, раз я не инсел, не кульхацкер, не прекариат.

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

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

vertexua ★★★★★
()
Последнее исправление: vertexua (всего исправлений: 1)
Ответ на: комментарий от Bioreactor

хайпили Моню и Шарпея.

с тех пор Шарпей переродился в один из самых больших и открытых OpenSource проектов и перелез на GNU/Linux

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

У чувака такая дикая неосознанка что он реально думает что им перечисленные языки «провалились», именно такую коннотацию несет сообщение. Хотя на каждом из них запросто найти горы работы, компаний, прибыльных стартапов.

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

Условно говоря, браузер Chromium на моём компе (Skylake, 16 Gb RAM, самсунговский m.2 pcie ssd) полностью собирается целую ночь, и после сборки занимает.... я не могу посмотрть сколько гигабайтов, потому что считаться будет минут десять. Скажем так, удивлюсь, если меньше 50 гигабайт.

На (по-моему, далеко не самых мощных) серверах Debian сборка занимает где-то 2h 44m .. 5h 52m (amd64) + 6m..10m (all), а места: 5.43 (amd64) + 2.56 (all) GB.

Но отладочные символы отсюда занимают подозрительно мало места.

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

Я собираю версию с максимальным дебагом, потому что вообще вся эта история со сборкой Хромиума нужна для того, чтобы понимать, как он работает и отлаживать спорные случаи

Плюс выше имелся в виду случай со «свежей» пересборкой. Последовательные пересборки, конечно, быстрее. Но только до тех пор, пока не поменян какой-то важный хидер, общий для большого количества файлов - тогда пиши пропало, мыло мочало начинай конпелировать весь мир сначала

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

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 1)
Ответ на: комментарий от stevejobs

Можно писать джаву, такую же быструю, как C/C++, но она будет дичайше некрасивая.

Так что, примеры будут? Или как всегда?

anonymous
()
Ответ на: комментарий от stevejobs

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

канпеляют маааахонький юнит, а ночью, когда все спят, собирается мир.

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

Как всегда мне лень тратить время на то, что меня совсем не интересует.

Как писать на Java супер красиво или наоборот - супер ресурсно-эффективно - это не ко мне. Мне важно во-первых, как писать resilient high thorughput приложения, во-вторых - как писать как можно проще и удобней для человека с минимальной квалификацией и желанием разбираться в теме (то есть это разговор о developer productivty).

Если тебе нужна «ресурсо-эффективная джава» (ака «байтоёбство», простите - но это стало термином) и «качественная джава» (обе, скорей всего, дико некрасивые) рекомендую ознакомиться с кодом CERN, они там всё на жабе пилят. Навскидку помню про Colt.

Другая часть вопроса - быстрая джава (не обязательно ресурсо-эффективная - зачастую вопрос скорости решается жертвоприношением денег на мегакластера). Это нужно обратиться в High Frequency Trading, в качестве иконы могу привести одного конкретного человека - Мартина Томпсона, автора LMAX Disruptor, Aeron, SBE и кучи других вещей, ведущего блог Mechanical Sympathy. Нужен конкретный пример - берешь код какого-нибудь Aeron и читаешь.

Из русскоязычных чуваков рекомендую послушать старые доклады Ромы Елизарова (старые - потому что он сейчас в JetBrains и теперь занимается котлином). Например, вот этот доклад хорошо показывает, почему «красивая и удобная» и «сверхбыстрая» джава - это разные вещи, там он рассказывает как им пришлось отказаться от типа String и использовать байтовые буфера.

Также мы делали хорошее интервью с Клиффом Кликом - отцом JIT-компиляции в Java и глобально, JIT-компиляции вообще, лежит по ссылке. Там тоже про то, что String нельзя использовать, нужно мучить буфера, причём в его случае - самомписные по особому феншую. Если нужен конкретный код, то стоит посмотреть на код его стартапа (стартап уже не его, но начинал он) под названием H2O - это сверхбыстрая машинлёнинг бигдата математика на чистой джаве, по ссылке.

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 3)
Ответ на: комментарий от stevejobs

Хм. Благодарю за развернутый ответ. На счет CERN, мне казалось у них всё на C++ теперь. Colt попахивает 20 летней давностью.

anonymous
()
Ответ на: комментарий от stevejobs

Вы рейтинг языков по моей ссылке смотрели?

Или Вы, как настоящий Ъ, не читатель, а писатель?

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

Да уж, помню как пытался собрать Хромиум (Haswell (i7-4790), 16Gb RAM), нифига так и не собралось (места ему не хватило), забил.

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

binary-trees
Go
Java

Хитрец, хитрец... Сейчас бы посравнивать машину, которая не умеет высвобождать память и жрет 2 гига на дереве глубиной 21 (4 млн элементов максимум выделяется процессом одновременно), с Go, который не превышает 400 Мб на том же тесте. Только что затестил на 12.0.1 и 1.13.1.

Как там народ шутит... «64 гигабайта должно хватить».

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

И то же самое в статике, например в плане юнитов компиляции. В обычном приложении на Java никто не скупится на классы. Любая сущность - это класс. В библиотеке Apache Camel как сейчас помню около 7000 классов - и это была одна из более сотни зависимостей того проекта. А потом и мы, обычные говнокодеры, за два месяца написали в этом проекте пару тысяч классов.

Да. То, что в хороших языках пишется одной строкой - в Жаве пишется отдельным файлом с объявлением класса и импортом модулей с именем на пол экрана. Я пишу 10 тысяч строчек - вы пишете две тысячи классов.

Условно говоря, браузер Chromium на моём компе (Skylake, 16 Gb RAM, самсунговский m.2 pcie ssd) полностью собирается целую ночь, и после сборки занимает.... я не могу посмотрть сколько гигабайтов, потому что считаться будет минут десять. Скажем так, удивлюсь, если меньше 50 гигабайт.

В С++ самая отвратительная сборка из известных мне языков - он бьет все рекорды по медленности сборки. Собирать программу на 15 строчек 3 секунды - это норма для крестов.

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

Хороший программист на Python обязан знать C хотя бы по той причине, что самая канонiчная реализация Python – CPython написана на нём.

чтуоооо? O_O

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

Можно писать джаву, такую же быструю, как C/C++, но она будет дичайше некрасивая.

Можно пример?

Не стоит забывать, что инструкции JVM очень близки к машинному коду. То есть, можно вырубить GC и руками управлять пулом памяти без высвобождения, а вычисляющий код будет работать с производительностью, близкой к сям. Естественно, написание и поддержка этого кода превратятся в кошмар.

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

Т.е. если скомпилировать в натив JS то бyдет медленнее V8? А то может зря я собрался писать компилирyемyю нодy.

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

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

Я понимаю, что могу сконцентрироваться на смысле решаемой задачи, а не на мелочах вроде перформанса.

Производительность кода, оказывается, теперь мелочь. А еще удивляемся от чего софт становится медленным. Джависты такие джависты.

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

Производительность кода, оказывается, теперь мелочь. А еще удивляемся от чего софт становится медленным. Джависты такие джависты

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

Намного более важно наличие возможности выбирать между скоростью разработки, скоростью работы, и надежностью. И Java в этом плане дает мало выбора. JVM - намного больше, благодаря многочисленным высокоуровневым языкам на ее основе.

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

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

Уже не новость, поэтому свалил на WM с консольным софтом и поменьше жирного софта. Pycharm вот заметно медленно загружает один единственный проект, хотя запускается с SSD. Джава, чтоб ее.

А всякие нетбинсы на десяток проектов вообще ппц.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

А всякие нетбинсы на десяток проектов вообще ппц.

Вообще-то, в IDE используется как раз та «быстрая как си» ява. Глупи козахски мальчик, похоже, не видел приплюснутых проектов в вижалстудии, которые пока открываются, можно сходить на кухню кофе налить (а то и попить).

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

Вообще-то, в IDE используется как раз та «быстрая как си» ява

Чушь и про быструю джаву тоже чушь, как сказали мне одни толковые дяди. Нельзя быть настолько медленным с одним проектом из 10 файлов (но похоже Pycharm еще и читает файлы библиотек в virtualenv). И неглупый дядя Стёпа должен был это понимать.

В общем, добавил себе в Vim пачку плагинов и вопрос с IDE закрыл. А всё, что на джаве, выпилю из системы (это ж Gentoo).

Deleted
()
Последнее исправление: Deleted (всего исправлений: 2)
Ответ на: комментарий от stevejobs

«красивая и удобная» и «сверхбыстрая» джава - это разные вещи

С C++, кстати, то же самое. И скорее всего с любым языком.

anonymous
()
Ответ на: комментарий от no-such-file

Я не флудила и не знаю что это такое. У кого-то из модераторов токсикоз на имя Лиза. Уже второй раз аккаунт стирают без всяких оснований.

anonymous
()
Ответ на: комментарий от byko3y

Естественно, написание и поддержка этого кода превратятся в кошмар.

На си аналог этого кода скорее всего будет проще поддерживать. Не говоря уже про с++ который очень часто позволяет завернуть такой код в нормальные и бесплатные абстракции.

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

На си аналог этого кода скорее всего будет проще поддерживать. Не говоря уже про с++ который очень часто позволяет завернуть такой код в нормальные и бесплатные абстракции.

Конечно же проще: специализированный инструмент побеждает специализированный инструмент из другой сферы (неродной).

Абстракции C++ не бесплатны - они оплачены эквивалентом миллиардов долларов в виде труда писателей компиляторов. Примерно как кодеры на JS привыкли «бесплатно» иметь быстрый интерпретатор, хоть, на самом деле, цена этого интерпретатора космическая. К тому же, попробуй поотлаживать на досуге оптимизированную программу на крестах. А ведь далеко не всегда прокатывает отладка на одной лишь отладочной версии. Это дистанция между машинным и исходным кодом оплачивается слёзами программистов.

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

Абстракции C++ не бесплатны

Тоже смотрел cppcon?

https://www.youtube.com/watch?v=rHIkrotSwcc

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

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

сделаем C++ почти таким же быстрым как Haskell.

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

Мимо кассы. Хаскель позволяет делать полностью императивные операции, но выглядит такой код ужасно, потому в таком стиле стараются не писать. К тому же, денег в оптимизитор хаскеля ввалено намного меньше, чем в онный для крестовых компиляторов.

По сути, это приводит к тому, что хаскель становится интерфейсом к императивным внутренностям, которые реализуют менеджер ввода-вывода, планировщик, GC, асинхронные сообщения, STM - саму императивку на хаскеле стараются не писать. Однако же, и запрещать никто не намерен.

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

О нем или хорошее, или ничего. Вот молчим

Clojure живее живых, ибо затесался под жабу. Мне было бы интересно услышать, как нынче поживают два других главных современных диалекта: Scheme и CL. Я догадываюсь, что Emacs Lisp весьма ограничен в применении, потому не упоминаю его.

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

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

Пора бы придумывать шуточки про C++, как то шутка про жаву с «64 Гб должно хватить». Ну вроде «hello world уже почти скомпилировался» и «я заголовок изменил - ложитесь спать».

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

Или умный GC поймёт что происходит треш и угар, и начнёт расстреливать сталинским методом - группируя в огромные блоки мусора и расстреливая за одну операцию блок целиком,

В log, выполняемой программы поместить warning.

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