Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2007.12.09;
Скачать: [xml.tar.bz2];

Вниз

Объясните пожалуйста дельфисту, что такое шаблоны в Си?   Найти похожие ветки 

 
homm ©   (2007-11-01 14:48) [40]

> [39] wendy parkinson   (01.11.07 14:47)
> Но у C# тоже есть один большой недостаток. 20 мегабайтный :)

В версии 3.0 уже 35 вроде. И все больше и больше…


 
Alkid ©   (2007-11-01 14:50) [41]


> Но у C# тоже есть один большой недостаток. 20 мегабайтный
> :)

Видишь ли, это сейчас для всего, кроме embedded систем и мобильный платформ, на которых я ни разу не специализируюсь, уже ОЧЕНЬ МАЛЕНЬКИЙ недостаток. Даже если учесть распухание framework`а, этот недостаток остаётся маленьким.

Зато программировать на С# быстрее и приятнее. :)


 
Alkid ©   (2007-11-01 14:52) [42]


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

А ты думал я тут буду глотку рвать, в стиле "don"t underestimate power of the Dark Side, son"? :)
Кстати, Ega23 ещё в самом начале ветки высказался в том же духе :)


 
Anatoly Podgoretsky ©   (2007-11-01 14:55) [43]

> Alkid  (01.11.2007 14:44:35)  [35]

> По сравнению с остальным делом - не трудное. Но это примерно как заворачивать винты отвёрткой, когда есть электический шуруповёрт. Можно, но удобнее с шуруповёртом.

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


 
Anatoly Podgoretsky ©   (2007-11-01 14:57) [44]


> general purpose strongly typed languages

Ой не надо к этому с++ приписывать.


 
Alkid ©   (2007-11-01 14:57) [45]


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

Значит пользовались шуруповёртами не той системы :)
У нас всё ок - админы с ними ходят, а мы, если что, отвёртками свои компы развиничаем :-)


 
homm ©   (2007-11-01 14:57) [46]

> [41] Alkid ©   (01.11.07 14:50)
> Видишь ли, это сейчас для всего, кроме embedded систем и
> мобильный платформ, на которых я ни разу не специализируюсь,
> уже ОЧЕНЬ МАЛЕНЬКИЙ недостаток.

Ага, уже любой пенсионер на свою пенсию и из любой деревни может выкачать из инета 30 метров. ;)


> [41] Alkid ©   (01.11.07 14:50)
> Зато программировать на С# быстрее и приятнее. :)

Зато программы уродские и тормозные получаются. Парадоксс.


 
Anatoly Podgoretsky ©   (2007-11-01 14:58) [47]

> wendy parkinson  (01.11.2007 14:47:39)  [39]

У тебя проблемы с винчестером, купи побольше.


 
Alkid ©   (2007-11-01 15:00) [48]


> Ага, уже любой пенсионер на свою пенсию и из любой деревни
> может выкачать из инета 30 метров. ;)

А у большинства пенсионеров в деревне вообще компов нет. Что, заря программисты вообще существуют?


> Зато программы уродские и тормозные получаются. Парадоксс.

Это из разряда "мне друг напел"? :)
Грамотно спроектированные решения на C# и выглядят красиво и по скорости исполнения обходят нативный С++ код на вычислительных задачах.


 
homm ©   (2007-11-01 15:04) [49]

> [48] Alkid ©   (01.11.07 15:00)
> и по скорости исполнения обходят нативный С++ код на вычислительных задачах.

Бла-бла-бла.


 
homm ©   (2007-11-01 15:05) [50]

Грамотно спроектированные решения на C# в виде пустой формы стартуют на Селероне500 с 128мб памяти 30 секунд. Куда уж там нативному коду…


 
DrPass ©   (2007-11-01 15:08) [51]


> Грамотно спроектированные решения на C# и выглядят красиво
> и по скорости исполнения обходят нативный С++ код на вычислительных
> задачах

Только следует уточнить - нативный С++ код, написанный дятлом


 
Anatoly Podgoretsky ©   (2007-11-01 15:13) [52]

> Alkid  (01.11.2007 14:57:45)  [45]

Наверно для того и ходят, что бы не развинчивали.


 
Anatoly Podgoretsky ©   (2007-11-01 15:14) [53]

> homm  (01.11.2007 14:57:46)  [46]

Посмотри тесты быстродействия на RSDN и удивись.


 
Alkid ©   (2007-11-01 15:15) [54]


> Бла-бла-бла.

Потрясающий по аргументированности ответ, однако :)
Постараюсь быть более аргументированным:
http://www.grimes.demon.co.uk/dotnet/man_unman.htm


 
Alkid ©   (2007-11-01 15:17) [55]


> Наверно для того и ходят, что бы не развинчивали.

Ну, столь глубоких мотивов выяснить не могу :)


 
Palladin ©   (2007-11-01 15:27) [56]


> wendy parkinson   (01.11.07 14:31) [33]

хм... Наличие виртуальных конструкоторов и VCL делает Delphi однозначно лучше среди языков своего класса


 
Alkid ©   (2007-11-01 15:32) [57]


> хм... Наличие виртуальных конструкоторов и VCL делает Delphi
> однозначно лучше среди языков своего класса

VCL - это библиотека, она к языку не очень относится. А вот виртуальные конструкторы - это 5!


 
homm ©   (2007-11-01 15:35) [58]

> [54] Alkid ©   (01.11.07 15:15)
> Постараюсь быть более аргументированным:
> http://www.grimes.demon.co.uk/dotnet/man_unman.htm

Ну и? Смотрим на столбец Optimized For Speed, и видим что результат в пределах погрешности. Смотрим на количество съеденой опреативы этими процессами, и сразу видим аутсайдера.


 
Palladin ©   (2007-11-01 15:38) [59]


> Alkid ©   (01.11.07 15:32) [57]

это я приплел, что бы MFC"ой не хвастались...


 
Alkid ©   (2007-11-01 15:41) [60]


> Ну и? Смотрим на столбец Optimized For Speed, и видим что
> результат в пределах погрешности. Смотрим на количество
> съеденой опреативы этими процессами, и сразу видим аутсайдера.

Ну, строго говря разница там примерно на прядок больше статистической погрешности :) А про количество съеденной памяти там вообще речи нет, и я про неё не говорил :)

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

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


 
Alkid ©   (2007-11-01 15:43) [61]


> это я приплел, что бы MFC"ой не хвастались...

MFC-ой хватались?! :) Не смеши меня. Такого монстра, как MFC я давно не видел. ИМХО одна из весьма неудачных классовых бибилиотек.

С другой стороны, если "говорим Делфьи, подразумеваем VCL", то в С++ такого нет. Хорошо это или плохо, но для С++ есть куча конкурирующих библиотек разного назначения.


 
homm ©   (2007-11-01 15:45) [62]

> [60] Alkid ©   (01.11.07 15:41)
> Но хочу показать, что утвержденияо "тормознутости" .NET
> как правило голословны.

Ага? [50]


 
homm ©   (2007-11-01 15:46) [63]

> [61] Alkid ©   (01.11.07 15:43)
> С другой стороны, если "говорим Делфьи, подразумеваем VCL",

Кто как.


 
homm ©   (2007-11-01 15:49) [64]

> [60] Alkid ©   (01.11.07 15:41)
> Ну, строго говря разница там примерно на прядок больше статистической
> погрешности :)

Ты меня не заставишь поверить в то, что в виндовс статистическая погрешность может быть меньше хотя-бы 10мс.


 
Alkid ©   (2007-11-01 15:52) [65]


> Ага? [50]

И что из этого следует? Ты сам понимаешь, что этот пример показывает нам, что .NET Run-Time инициализируется медленее, чем Run-Time нативных приложений, но это ничего не говорит о скорости выполенния самих программ.


 
Alkid ©   (2007-11-01 15:57) [66]


> Ты меня не заставишь поверить в то, что в виндовс статистическая
> погрешность может быть меньше хотя-бы 10мс.

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


 
homm ©   (2007-11-01 15:57) [67]

> [65] Alkid ©   (01.11.07 15:52)
> но это ничего не говорит о скорости выполенния самих программ.

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


 
umbra ©   (2007-11-01 15:59) [68]


> это ничего не говорит о скорости выполенния самих программ.

так выполняется же в любом случае нативной код, хоть в .NET, хоть в С++. Поэтому выражение ".NET быстрее нативного кода" бессмысленно.


 
Palladin ©   (2007-11-01 16:01) [69]


>  Такого монстра, как MFC я давно не видел. ИМХО одна из
> весьма неудачных классовых бибилиотек.



> С другой стороны, если "говорим Делфьи, подразумеваем VCL",
>  то в С++ такого нет.


эт точно... но все равно грех VCL не упомянуть... :)


 
Mystic ©   (2007-11-01 16:05) [70]

> Но хочу показать, что утвержденияо "тормознутости" .NET
> как правило голословны.


После такого рода заявлений я решил попробовать C#. Выбрал себе задачу (шахматы, генератор ходов), для которой критична производительность (сила напрямую зависит от количества позиций в секунду). Понеслась.

Итак, как хотелось бы представить себе поле? Поскольку очень хотелось бы, чтобы была допустима запись

using namespace Chess;

Field x = Field.A1;
Bitboard test = x.GetBitboard();

и т. д., то первой мыслью было объявить тип Field не как enum, а как struct, наподобие System.Drawing.Color. Итак


   struct Field
   {
       private int index;

       private Field(int _index)
       {
           index = _index;
       }

       public Field(Field Orig)
       {
           index = Orig.index;
       }

       public static bool operator ==(Field a, Field b)
       {
           return a.index == b.index;
       }

       public static bool operator !=(Field a, Field b)
       {
           return a.index != b.index;
       }

       /* Просят объявить, хотя я его использовать не собираюсь */
       public override bool Equals(object a)
       {
           if (typeof(Field) != a.GetType()) return false;
           return this == (Field)a;
       }

       /* Тоже надо */
       public override int GetHashCode()
       {
           return index.GetHashCode();
       }

       static public Field A1
       {
           /* Оптимизация, потому что return new Field(0) приводит к unboxing */
           get
           {
               Field Data;
               Data.index = 0;
               return Data;
           }
       }

       static public Field B1
       {
           get
           {
               Field Data;
               Data.index = 1;
               return Data;
           }
       }

   }


И использовал его я, как и хотел, так:


       static int Test()
       {
           Chess.Field Test = Chess.Field.A1;
           if (Test == Chess.Field.A1)
               return 0;
           else if (Test == Chess.Field.B1)
               return 1;
           return -1;
       }


Скомпилировал в релизе, опция Optimize Code стоит. Смотрю что вышло:


;        static int Test()
;        {

00000000  sub         rsp,48h  ; Инициализация фрейма стека

00000004  mov         r8d,4    
0000000a  xor         edx,edx
0000000c  lea         rcx,[rsp+20h]
00000011  call        FFFFFFFFFF514BA0 ; Вызов не расшифрован

00000016  nop              
00000017  mov         rax,64280013128h
00000021  mov         eax,dword ptr [rax]
00000023  test        eax,eax
00000025  je          000000000000002C
00000027  call        FFFFFFFFFF78DDC0 ; Вероятно обращение к JIT-компилятору

;            Chess.Field Test = Chess.Field.B1;
0000002c  call        FFFFFFFFFFFFFFD8
00000031  mov         dword ptr [rsp+2Ch],eax
00000035  mov         eax,dword ptr [rsp+2Ch]
00000039  mov         dword ptr [rsp+20h],eax

;            if (Test == Chess.Field.A1)
0000003d  mov         eax,dword ptr [rsp+20h]
00000041  mov         dword ptr [rsp+24h],eax
00000045  call        FFFFFFFFFFFFFFD0
0000004a  mov         dword ptr [rsp+30h],eax
0000004e  mov         edx,dword ptr [rsp+30h]
00000052  mov         ecx,dword ptr [rsp+24h]
00000056  call        FFFFFFFFFFFFFFB0
0000005b  mov         byte ptr [rsp+34h],al
0000005f  movzx       eax,byte ptr [rsp+34h]
00000064  test        eax,eax
00000066  je          000000000000006C

;                return 0;
00000068  xor         eax,eax
0000006a  jmp         00000000000000A5

;            else if (Test == Chess.Field.B1)
0000006c  mov         eax,dword ptr [rsp+20h]
00000070  mov         dword ptr [rsp+28h],eax
00000074  call        FFFFFFFFFFFFFFD8
00000079  mov         dword ptr [rsp+38h],eax
0000007d  mov         edx,dword ptr [rsp+38h]
00000081  mov         ecx,dword ptr [rsp+28h]
00000085  call        FFFFFFFFFFFFFFB0
0000008a  mov         byte ptr [rsp+3Ch],al
0000008e  movzx       eax,byte ptr [rsp+3Ch]
00000093  test        eax,eax
00000095  je          000000000000009E

;                return 1;
00000097  mov         eax,1
0000009c  jmp         00000000000000A5

;            return -1;
0000009e  mov         eax,0FFFFFFFFh
000000a3  jmp         00000000000000A5
000000a5  add         rsp,48h
000000a9  rep ret


Остальное не лучше... Вместо нескольких ассемблерных инструкций переливание из пустого в порожнее...


 
Mystic ©   (2007-11-01 16:06) [71]

Может это я не знаю, как писать? Попробовал скомпилировать такой код:


           System.Drawing.Color Color = System.Drawing.Color.Black;
           if (Color == System.Drawing.Color.Black)
               System.Console.WriteLine("Catastrophic execution");


Результат:


;            System.Drawing.Color Color = System.Drawing.Color.Black;
0000005c  lea         rcx,[rsp+40h]
00000061  call        FFFFFFFFF5A8CBF0
00000066  mov         qword ptr [rsp+000000D0h],rax
0000006e  lea         rcx,[rsp+40h]
00000073  mov         rax,qword ptr [rcx]
00000076  mov         qword ptr [rsp+20h],rax
0000007b  mov         rax,qword ptr [rcx+8]
0000007f  mov         qword ptr [rsp+28h],rax
00000084  mov         rax,qword ptr [rcx+10h]
00000088  mov         qword ptr [rsp+30h],rax

;            if (Color == System.Drawing.Color.Black)
0000008d  lea         rcx,[rsp+20h]
00000092  mov         rax,qword ptr [rcx]
00000095  mov         qword ptr [rsp+58h],rax
0000009a  mov         rax,qword ptr [rcx+8]
0000009e  mov         qword ptr [rsp+60h],rax
000000a3  mov         rax,qword ptr [rcx+10h]
000000a7  mov         qword ptr [rsp+68h],rax
000000ac  lea         rcx,[rsp+70h]
000000b1  call        FFFFFFFFF5A8CBF0
000000b6  mov         qword ptr [rsp+000000D8h],rax
000000be  lea         rcx,[rsp+70h]
000000c3  mov         rax,qword ptr [rcx]
000000c6  mov         qword ptr [rsp+000000B0h],rax
000000ce  mov         rax,qword ptr [rcx+8]
000000d2  mov         qword ptr [rsp+000000B8h],rax
000000da  mov         rax,qword ptr [rcx+10h]
000000de  mov         qword ptr [rsp+000000C0h],rax
000000e6  lea         rcx,[rsp+58h]
000000eb  mov         rax,qword ptr [rcx]
000000ee  mov         qword ptr [rsp+00000090h],rax
000000f6  mov         rax,qword ptr [rcx+8]
000000fa  mov         qword ptr [rsp+00000098h],rax
00000102  mov         rax,qword ptr [rcx+10h]
00000106  mov         qword ptr [rsp+000000A0h],rax
0000010e  lea         rdx,[rsp+000000B0h]
00000116  lea         rcx,[rsp+00000090h]
0000011e  call        FFFFFFFFF5A7DEA0
00000123  mov         byte ptr [rsp+000000E0h],al
0000012a  movzx       eax,byte ptr [rsp+000000E0h]
00000132  test        eax,eax
00000134  je          0000000000000148

;                System.Console.WriteLine("Catastrophic execution");
00000136  mov         rcx,12969090h
00000140  mov         rcx,qword ptr [rcx]
00000143  call        FFFFFFFFF81DFAE0


 
Anatoly Podgoretsky ©   (2007-11-01 16:06) [72]

> Alkid  (01.11.2007 15:57:06)  [66]

И статистика, а не разовое выполнение.


 
Mystic ©   (2007-11-01 16:08) [73]

Примерно в том же ключе. Видимо так писать еще рано. Попробовал другой путь --- просто использовать Enum. Тут я решил сразу писать код, используя напрямую работу с типами int, System.UInt64 и т. д. Итак, общая структура


   enum Field
   {
       A1, B1, C1, D1, E1, F1, G1, H1,
       A2, B2, C2, D2, E2, F2, G2, H2,
       A3, B3, C3, D3, E3, F3, G3, H3,
       A4, B4, C4, D4, E4, F4, G4, H4,
       A5, B5, C5, D5, E5, F5, G5, H5,
       A6, B6, C6, D6, E6, F6, G6, H6,
       A7, B7, C7, D7, E7, F7, G7, H7,
       A8, B8, C8, D8, E8, F8, G8, H8
   }

       public static System.UInt64 MakeBitboard(Field A)
       {
           return (System.UInt64)1 << (System.Byte)A;
       }


Итак, в этот раз код получился лучше:


;        static int Test()
;        {
00000000  sub         rsp,48h
00000004  mov         dword ptr [rsp+20h],0
0000000c  mov         qword ptr [rsp+28h],0
00000015  mov         rax,64280013128h
0000001f  mov         eax,dword ptr [rax]
00000021  test        eax,eax
00000023  je          000000000000002A
00000025  call        FFFFFFFFFF78DE00

;            Chess.Field A = Chess.Field.B1;
0000002a  mov         dword ptr [rsp+20h],1

;            System.UInt64 Test = Chess.Engine.MakeBitboard(A);
00000032  mov         ecx,dword ptr [rsp+20h]
00000036  call        FFFFFFFFFFFFFFE0
0000003b  mov         qword ptr [rsp+30h],rax
00000040  mov         rax,qword ptr [rsp+30h]
00000045  mov         qword ptr [rsp+28h],rax

;            if (Test == 0x01)
0000004a  cmp         qword ptr [rsp+28h],1
00000050  jne         0000000000000056

;                return 0;
00000052  xor         eax,eax
00000054  jmp         000000000000006C

;            else if (Test == 0x02)
00000056  cmp         qword ptr [rsp+28h],2
0000005c  jne         0000000000000065

;                return 1;
0000005e  mov         eax,1
00000063  jmp         000000000000006C

;            return -1;
00000065  mov         eax,0FFFFFFFFh
0000006a  jmp         000000000000006C
0000006c  add         rsp,48h
00000070  rep ret    
;        }


и

;        public static System.UInt64 MakeBitboard(Field A)
;        {
00000000  mov         dword ptr [rsp+8],ecx
00000004  sub         rsp,28h
00000008  nop              
00000009  mov         rax,64280013128h
00000013  mov         eax,dword ptr [rax]
00000015  test        eax,eax
00000017  je          000000000000001E
00000019  call        FFFFFFFFFF78DD50

;            return (System.UInt64)1 << (System.Byte)A;
0000001e  movzx       ecx,byte ptr [rsp+30h]
00000023  and         ecx,3Fh
00000026  mov         eax,1
0000002b  shl         rax,cl
0000002e  jmp         0000000000000030
00000030  add         rsp,28h
00000034  rep ret          
;        }


В этот раз много лучше, но все-таки остаются вопросы:
(а) Разве трудно догадаться сделать вызов функции MakeBitboard inline-ом? Или хотя-бы дать возможность его объявить...
(б) Почему не упростить фрейм функции? Если это вызов JIT-компилятора, то почему не делать обращения к нему до инициализации стека и не затирать впоследствие обращение к нему?
(в) Почему не использовать для хранения локальных переменных регистры, коих в ADM64 дочерта?
(г) В чем смысл jmp 0000000000000030 в функции MakeBitboard?
(д) Зачем использовать передачу параметров через регистры, если потом их копировать в стек?


 
Anatoly Podgoretsky ©   (2007-11-01 16:09) [74]

> homm  (01.11.2007 15:57:07)  [67]

Это расплата за ООП, за managed code, за рантайм вынесеный на уровень системы и прочие прелести.
Дельфи в этом плане находится там же. А если какой ни будь Power Buider / Ява и другие продукты с большим рантаймом.


 
Джо ©   (2007-11-01 16:12) [75]

[71] Mystic ©
Ужас. Честно, ужас.


 
homm ©   (2007-11-01 16:14) [76]

> [70] Mystic ©   (01.11.07 16:05)
> Выбрал себе задачу (шахматы, генератор ходов), для которой
> критична производительность (сила напрямую зависит от количества
> позиций в секунду). Понеслась.

Что вышло то по тестам?


 
Джо ©   (2007-11-01 16:18) [77]

> [76] homm ©   (01.11.07 16:14)
> > [70] Mystic ©   (01.11.07 16:05)
> > Выбрал себе задачу (шахматы, генератор ходов), для которой
>
> > критична производительность (сила напрямую зависит от
> количества
> > позиций в секунду). Понеслась.
>
> Что вышло то по тестам?

А какое там может выйти быстродействие, если даже if (Color == System.Drawing.Color.Black) разворачивается в такой ужас?


 
homm ©   (2007-11-01 16:20) [78]

> [77] Джо ©   (01.11.07 16:18)
> А какое там может выйти быстродействие, если даже if (Color
> == System.Drawing.Color.Black) разворачивается в такой ужас?

Есть мнение что это промежуточный асемблер…
Так все-же?


 
Mystic ©   (2007-11-01 16:28) [79]

> homm ©   (01.11.07 16:14) [76]

До тестов я не дошел. Для меня важнее было не сравнить C# с C++, а сравнить мой генератор ходов с другими. К тому же шахматные программы используют хэш позиций, размер которого задается заранее. Например, я задаю в качестве параметра размер кэша в один гигабайт, и если число информации в кэше подходит к этому значению, то устаревшие/боковые позиции из него удаляются. Хорошей идеи как это реализовать в C# я не нашел. Ну и по совокупности C# был признан языком, не адекватным поставленной задачи :)

Есть чистый генератор + парсер PGN на Pure C, если интересно. Могу выслать для ознакомления при условии неразглашения :)


 
Mystic ©   (2007-11-01 16:37) [80]

> Есть мнение что это промежуточный асемблер…

Это мне показал cordbg.exe. Скомпилировано в релизе.



Страницы: 1 2 3 4 5 вся ветка

Форум: "Прочее";
Текущий архив: 2007.12.09;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.66 MB
Время: 0.051 c
2-1195110089
VladSot
2007-11-15 10:01
2007.12.09
Вопрос по TListView


15-1194269268
Моб
2007-11-05 16:27
2007.12.09
Выбор мобильника.


15-1194596998
turbouser
2007-11-09 11:29
2007.12.09
Штрихкод


15-1194525911
Sonia
2007-11-08 15:45
2007.12.09
Может еще кто-то помнит Фортран....


2-1195010825
Brave
2007-11-14 06:27
2007.12.09
Что то непонятне с компилятором? Или я неумею программировать?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский