LINUX.ORG.RU

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

 


1

3

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



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

С++ кошмарно долго компилируется

2 минуты на компиляцию и сборку 75MB исходных текстов кошмар?

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

С++ кошмарно долго компилируется

Что-то в вашей консерватории, использующей C++ «не так».
C++, то причем здесь?

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

Если у тебя мегамонстр, то логично вынести фичи в библиотеки, чтобы компилировать только их, если API менять не надо и не надо вносить новые фичи.

Разнос отдельных фич по независимым библиотекам сам по себе намного усложняет разработку. Именно потому столько крупных проектов разрабатывается в виде монолита: linux, windows, oracle, mysql, chromium, firefox - это только самые известные. Да, какие-то их части друг к другу ближе, какие-то - дальше, но по цепочке они неразрывно связаны друг с другом, и оторвать какой-то кусок системы не получится.

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

Компилятор в машинный код есть. В общем случае value types появятся года через два, их не делали потому что было не очень нужно, но сейчас уже всё самое важное сделали и можно взяться за мелочи.

Насчёт всего остального, оно есть в частном случае. Мувы и прочее там есть, просто ведаешь ими не ты, а искусственный интеллект - божественный сборщик мусора. Не сказать чтобы так мог сделать кто угодно, но вот конкретно я могу пойти и добавить любую интринсику, сделав ассемблерную реализацию любой функции. Делал ли я это на практике? Нет. А зачем?

Но на самом деле, всё это не очень нужно. Джава - это специальная система для написания безопасного продакшенового кода для больших энтерпрайзов, утилизирующего возможность Больших Серверов и Больших Кластеров, силами огромных команд.

Если у тебя на проде закончилась оперативка - это как правило значит, что в прод нужно воткнуть больше оперативки. Никто не полезет менять приложение, если это не что-то супер критическое.

Выделение памяти на стеке - это штука не супер критическая.

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

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

Приведу простой пример.
SQLite отличный проект.
Если вы не собираетесь расширить его функциональность, то amalgamation файл «самое то».
Разбираться с internal amalgamation файл занятие «не для слабонервных».
Поэтому, когда возникла необходимость разобраться с архитектурой SQLite, сразу сделал Solution в котором все «по полочкам» разложено.
И сразу код SQLite превратился в «красавца», а «не читаемого монстра».

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

Разбираться с internal amalgamation файл занятие «не для слабонервных».
Поэтому, когда возникла необходимость разобраться с архитектурой SQLite, сразу сделал Solution в котором все «по полочкам» разложено.
И сразу код SQLite превратился в «красавца», а «не читаемого монстра».

Молодец. Но каким образом это относится к нашему обсуждению?

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

Это был ответ на ваше суждение

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

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

А вот любопытно - «Чем усложняет разработку?».

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

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

Самое смешное то, что нынче в эту же нишу весьма активно лезет JavaScript. Безопасен он в том смысле, что простая макака не сможет на нем написать сегфолт даже при желании. В каком-то смысле это методика «заваливания ресурсами» задачи, в результате чего задача прогибается и поддается под действием этой грубой силы.

Отсюда возникает понимание того, почему этот метод не прокатывает в мелких проектах - у них просто нет столько ресурсов, чтобы этими ресурсами разбрасываться: 60 Гб оперативы сюда, 60 Гб туда, и еще по 60 Гб в сорок серверов.

Такой расклад, в каком-то смысле, был удобен Sun-у в начале двухтысячных с его жирным железом, но нынче даже он становится сомнительным, потому как садить макак кодить жаву хоть и безопасно, но малопроизводительно в плане скорости разработки в силу фундаментальной убогости языка. К тому же, если заказчик таки хочет хороший результат, то приходится брать хороших программистов, а их не так просто найти и/или они много стоят - садить их чистить вилкой говно было бы довольно расточительно. По этой причине происходит дрейф в сторону JS/Python/Scala/Clojure/etc, которые экономят ресурсы разработчиков и транжирят ресурсы железа.

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

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

Собственно хотел этим привести пример, когда монолитный код «уместен».
А вот любопытно - «Чем усложняет разработку?».

Амальгамация SQLite меняет форму, никак не меняя содержание. Да, амальгамированную форму компиляторы немного лучше оптимизируют. В любом случае - это не разбиение на компоненты и не имеет отношения к обсуждению.

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

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

Пример привести можете?

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

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

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

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

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

Пример привести можете?

Вообще-то, уже привел.
Оптимизация в питоне? (комментарий)
Упомянутым мной проектам нет аналогов в модульном виде. Ну, то есть, вообще-то есть, но эти аналоги не могут конкурировать с лидерами.

Почему независимая модульность усложняет разработку - это вопрос типа «почему трава зеленая?» и «почему небо голубое?»: любая попытка непосредственно прикоснуться к объекту вопроса почти со всех сторон подтвердит, что да, так оно и есть. Почему нельзя вынести драйвера из исходников линукса? Потому что драйвера начнут отваливаться, глючить, переставать компилироваться. Зафиксируй ABI/API - и вот ты уже теряешь возможности развития, оказываясь вынужденым поддерживать совместимость во веки веков, аминь.

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

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

Усложняет дурак на должности тимлида, который не хочет думать про архитектуру и API, а хочет фигак-фигак и в продакшен, благо менеджер гонит быстрее.

У «дурака» система будет уже в продакшене, он уже будет заниматься доработкой отдельных модулей, пока ты, умный, будешь делать свою идеальную архитектуру и API, которые все равно в итоге придется переделывать, потому что требования постоянно меняются и уточняются. Есть очень простое правило для прикладного софтописания: уже работающая архитектура всегда лучше архитектуры, которая еще не работает. А когда неработающая архитектура наконец заработает, то тогда и можно будет судить о том, какая из двух работающих оказалась лучше. И еще не факт, что долгая архитектура когда-то сможет догнать давно работающую.

В том же oracle баг уже фиксится около месяца. Скоро будут вынужденны переписывать или отомрут перед каким-то постгрискул.

Оракл можно уже закапывать. Это самая быстрая реляционная СУБД на рынке, но ее поддержка очень дорого обходится и на ней экономят. Они могли бы вкладывать кучу ресурсов в СУБД, но не будут это делать, потому что вполне оправдано не видят коммерческой перспективы. Также, они могли бы отбросить вопросы совместимости, сделать что-то новое, более простое и удобное в поддержке, но это не взлетит - они держатся на инерции. Скорее, «новое» здесь - это MySQL, который они приобрели.

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

У «дурака» система будет уже в продакшене

Я много стартапов повидал. В большинстве случаев дурак разоряется, если не соображает, когда надо гнать, а когда не надо.

«новое» здесь - это MySQL, который они приобрели

Ничего что его тоже скоро закапыввать?

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

Я много стартапов повидал. В большинстве случаев дурак разоряется, если не соображает, когда надо гнать, а когда не надо.

Проекты Илона Маска - типичный пример херак-херак и в продакшн. Например, Tesla и OpenAI. И прокатывает, никто не жалуется, почему-то. MongoDB, MySQL, Docker - ведь все эти проекты держались на честном слове, на старте не имея за собой толком никакой архитектуры. Ты скажешь, что ты бы лучше сделал?

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

Например, Tesla и OpenAI

Что характерно оба убыточны или без прибыли. В OpenAI вообще <10 сотрудников всегда было. SpaceX тот прибыльный, но там не так фигак-фигак и в продакшен.

Ты скажешь, что ты бы лучше сделал?

ХЗ. Но вот Леня пришел и говно из Линуксов вынес.

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

Что характерно оба убыточны или без прибыли. В OpenAI вообще <10 сотрудников всегда было. SpaceX тот прибыльный, но там не так фигак-фигак и в продакшен.

Да, убыточны, но успешны. SpaceX вообще не софт разрабатывают так-то.

ХЗ. Но вот Леня пришел и говно из Линуксов вынес.

Не знаю, кто такой Леня.

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

Но вот Леня пришел и говно из Линуксов вынес.

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

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

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

20% клиентов требуется 80% мощностей

но там ещё осталось 80% людей и компаний, которым никакой перформанс на фиг не нужен.

бизнес, который занимается например бухгалтерской документацией, у них большая часть бабла уйдёт во всякие зарплаты, то что сервак на C++ стоил бы 500 рублей в месяц, а сервак на JS стоит десять тысяч для них вообще незаметная величина. Значимость перформанса растёт с эффектом масштаба, а в той же России масштабных компаний по пальцам пересчитать

и вот здесь JS рулит, перформанс у него не то чтобы высокий, но *достаточный* для большинства применений

в целом, у любого современного рантайма (даже у cpython!), кажется, хватает перформанса для того, чтобы решать любую из задач для тех самых 80%

поэтому на первый план выходит удобство использования. Например, дата сатанизм удобней делать на питоне, а писать клёвые маленькие веб-приложения удобней на JS.

я сейчас на JS пишу скрипты, как когда-то на баше

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

На таком высоком уровне ты ничего не оптимизируешь. Тут работают только оптимизации на уровне алгоритмов.

И профайлер в этом деле не менее полезен, чем следование «банальным принципам»

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

Тут работают только оптимизации на уровне алгоритмов.

Кстати недавно посмотрел видос с Александреску: https://youtu.be/FJJTYQYB1JQ

Оптимизация на уровне алгоритмов достаточно плохо работает. Он там захотел обогнать С++ std::sort, и когда он придумал умные оптимизации которые сокращали число операций, всё работало медленнее, тогда он стал делать «глупые вещи», которые не должны работать по всяким кнутам, и пришёл к успеху.

Если нет времени смотреть всю беседу, то вот два скрина:

https://imgur.com/a/3j5a6Ub

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

Речь про питон, эти рассуждения здесь вообще не релевантны. Пытаться попадать в кеш, например, равносильно стрельбе из nerf gun по мишеням с 500 метров. Нужно просто писать идиоматичный код и не делать резких движений.

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

Мне как-то доклад попадался «Как перестать профилировать и начать приносить пользу», не могу найти, но там про сисярп, правда. Суть такая: не слушай Кнута пиши нормально сразу, когда ты начинаешь профилировать, значит ты уже знатно наговнял. Я в общем-то согласен, когда ты начинаешь профайлить, ты расписываешься в том, что не одупляешь, что у тебя в коде происходит.

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

в целом, у любого современного рантайма (даже у cpython!), кажется, хватает перформанса для того, чтобы решать любую из задач для тех самых 80%

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

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

Мне как-то доклад попадался «Как перестать профилировать и начать приносить пользу», не могу найти, но там про сисярп, правда. Суть такая: не слушай Кнута пиши нормально сразу, когда ты начинаешь профилировать, значит ты уже знатно наговнял. Я в общем-то согласен, когда ты начинаешь профайлить, ты расписываешься в том, что не одупляешь, что у тебя в коде происходит.

Сложно говорить, не имея конкретного примера, который, я так понимаю, приводился в докладе. Я соглашусь, разве что, с тем, что нельзя со старта писать прям уж полное безобразие. Но и вылизывать код изначально тоже не имеет смысла - ты проведешь 90% времени на вещах, которые работают 10% времени. А наговняешь ты всегда, в любом раскладе - вопрос, скорее, в том, сможешь ли ты быстро исправить свою ошибку или нет.

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

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

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

Проекты Илона Маска - типичный пример херак-херак и в продакшн. Например, Tesla и OpenAI. И прокатывает, никто не жалуется,

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

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

Не знаю, кто такой Леня.

Это тот, кто «говно из Линуксов вынес.».
Но вот беда, еще есть Вася, который «принесет говна в Линукс больше Лени».

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

Как сказал бы царь - «Нужно пацанам объснять все просто так, чтобы им было все понятно».

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

Кстати это - «проект Лени из Аризоны».

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

вылизывать код изначально

Об этом тоже речи нет.

Основная идея Кнута в том, что найдя явно тормозящие места и пофиксив их, ты окажешься в мире холодного пива и мокрых маек. Но, что если таких мест в коде не будет? Что если код в целом не очень? Тупик.

Пусть даже такое место есть. Ты отпрофайлишь, подумаешь и обнаружишь, например, что данные у тебя размазаны, а обеспечив локальность ты получишь ускорение в 1000 раз. Замечельно, сам создал с проблему, сам героически с ней справился. Но что мешало изначально об этом подумать?

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

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

Основная идея Кнута в том, что найдя явно тормозящие места и пофиксив их, ты окажешься в мире холодного пива и мокрых маек. Но, что если таких мест в коде не будет? Что если код в целом не очень?

Таких мест не будет только в том случае, если их уже исправили. В противном случае они точно есть.

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

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

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

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

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

В противном случае они точно есть

По количеству функций/методов в коде.

мягко говоря, не единственная вещь

Ты пропустил слово «например» или включил режим шланга?

вылизывать код изначально

Об этом тоже речи нет

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

Однозначно режим шланга. И ничего ты не перепишешь, одно изменение потянет второе, второе потянет третье и ты обосрёшься. Если ты изначально об этом совсем не думал, код пожет быть непригодным для оптимизации в принципе.

Есть сотни самых разных вещей

я должен каждую помнить при написании каждой строчки?

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

Ещё раз: идея в том, чтобы изначально писать приличный код с оглядкой на оптимизацию. Тогда тебе ей заниматься придётся очень не скоро, либо вообще никогда.

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

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

+100. Если код планируется быть быстрым, то его нужно сразу писать с заделом на скорость. Даже книги есть, которые пытаются научить так писать, гуглить по Data Driven Development.

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

В противном случае они точно есть

По количеству функций/методов в коде.

Что по количеству кода?

мягко говоря, не единственная вещь

Ты пропустил слово «например» или включил режим шланга?

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

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

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

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

У питона огромный потенциал для оптимизации узких мест. А банальщина вроде «используйте list comprehension вместо цикла», может быть, и ускоряет выполнение, но, что более важно, является более читаемой, чем цикл - это упрощение конструкций естественным образом ведет к ускорению работы, но Кнут писал совсем про другое, и это «совсем другое» (настоящая оптимизация узких мест) в питоне весьма трудоемко, потому должно проводиться по необходимости и только после профилирования.

Еще раз: это не оптимизация - это просто хороший стиль письма.

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

Если код планируется быть быстрым, то его нужно сразу писать с заделом на скорость.

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

Даже книги есть, которые пытаются научить так писать, гуглить по Data Driven Development.

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

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

Если код планируется быть быстрым

то надо писать на С. Ваш К.О.

Ну, кресты тоже умеют косить под Си. Да и в CPython много работы выполняют функции на Си.

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

до Поттеринга был код, но его выкинули на помойку

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

Ты не писал в своем сообщении, что путей оптимизации может быть много

Ты в своём сообщении не написал, что ты не дебил. Будем, считать, что ты дебил. На этом и закончим.

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

У тебя? Сочувствую.

Я отшил поциента, который полностью игнорирует мной написанное и общается сам с собой.

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

кресты тоже умеют косить под Си.

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

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

Я уже довольно много в теме про ООП и ФП описывал, чего не хватает Си и чего хватает крестам с излишком, с очень большим и неприятным излишком. В GCC завезли атрибут cleanup, но вот беда - в других компиляторах его нету.

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

В GCC завезли атрибут cleanup, но вот беда - в других компиляторах его нету

в clang тоже завезли. Если без defer жизнь не мила, то вот пример того, как это можно сделать. Да и другие реализации где-то встречал, просто популярность такого подхода в среде сишников примерно нулевая. Зачем городить огород, если в подавляющем большинстве случаев можно обойтись банальным goto?

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