Привет!

Сегодня я представлю вам мой любимый язык программирования loli.
Чем меня он так заинтересовал?

Новый язык программирования очень близок по скорости с C++, но интерпретируется.
Для начала немного расскажу про сам язык.

Loli — это встраиваемый объектно-ориентированный язык программирования, в последнее время набирающий популярность. Проще говоря, это скриптовой язык программирования.

Сразу покажу вам пример на loli:

import time

fn thread_function
{
   for i in 0...10000000: {
       var e = i * i
   }
}

import threads

var start_time = time.Time.clock()
var thread = threads.create(thread_function)

sayln(time.Time.clock() - start_time ++ " seconds")

Этот пример выполняет множественный перебор, присваивание и возведение в степень.
На выполнение ушло 41.8174 сек.

Тот же пример на языке C++:

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdint.h>

static void * thread_fn() {
    double start_time = ((double)clock())/(double)CLOCKS_PER_SEC;
    for (uint64_t i = 0; i < 10000000; i++) {
        auto unsigned int _e =  i * i;
    }
    printf("%lf seconds\n", ((double)clock())/(double)CLOCKS_PER_SEC - start_time);
    return 0;
}

int main() {
    pthread_t pthread = NULL;
    pthread_create(&pthread, NULL, thread_fn, NULL)
    pthread_join(&pthread, NULL);
    return 0;
}

Скомпилированный с помощью GCC, выполняется на той же машине за 35.5917 сек.

Как мы можем заметить, разница в производительности двух довольно популярных языков составляет ~10%, что является отличным результатом для скриптового языка программирования.

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

Что происходит вокруг языка


На loli уже давно портированы различные фреймворки для мультимедиа, разработки видео-игр и обработки данных такие как FreeGLUT, LoliGL, Lurl, loli-json.

На данный момент портируются Cairo, Pango, Freetype и GTK+ для создания пользовательского интерфейса, а также OpenCV для машинного зрения.

Авторы планируют также портировать остальные наиболее популярные технологии машинного обучения.

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

Ссылки:

Комментарии (47)


  1. farcaller
    24.02.2019 17:04
    +11

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

    когда он созреет — его переименуют?


    1. fireSparrow
      24.02.2019 21:24
      +4

      Очевидно да, т.к. созревшая девушка — по определению уже не лоли.


      1. ProRunner
        24.02.2019 22:20

        2 статьи опубликованы примерно в одно время, ссылка для связи:
        habr.com/ru/post/441512


  1. DrPass
    24.02.2019 17:08
    +8

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


    1. MWGuy
      24.02.2019 17:23

      Потоки в Loli реализуются с помощью этого расширения github.com/loli-foundation/loli-threads


  1. bogolt
    24.02.2019 17:14
    +2

    Во-первых ваш код не компилируется, поэтому я не очень понимаю как вы получили возвращаемое значение.
    Во-вторых на моем компе если исправить все ошибки он выдаст 0.021808 seconds
    В третьих как известно оптимизатор выбросит ненужное, поэтому не уверен что код в цикле будет на самом деле выполняться.
    Если все же сделать чтобы значение _e использовалось то время выполнения программы на си возросло у меня до 0.044946 секунд.

    Еще один эксперимент я провел на самой слабой доступной мне виртуалке ( там АРМ какой-то ) и получил 0.167762 секунд на выполнение.


    1. yurrig
      24.02.2019 17:35

      А если еще uint64_t заменить на int (или не заменять, но собрать в 64бит моде), то и вовсе падает с 43 до 4 мс. Пробовал под VS2017.


      1. dev96
        24.02.2019 18:01
        -1

        Ну как-бы правильнее юзать везде и всегда size_t.


        1. yurrig
          24.02.2019 18:16
          +1

          Ну как-бы правильнее юзать везде и всегда size_t.

          Только если речь идет о количествах к-либо объектов.


          1. dev96
            24.02.2019 18:23

            Само собой)


    1. TheDaemon
      25.02.2019 08:18

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


      1. bogolt
        25.02.2019 12:50

        Я же написал об этом

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


        сделал так чтобы значение _e выводилось в последнем принте, тот же который выводит время, и получил 0.04 секунды


  1. half-life
    24.02.2019 17:49
    +4

    В пайтоне есть import this
    А здесь есть import desu?


    1. MWGuy
      24.02.2019 17:50

      Нет, тут нельзя так сделать


  1. AIshutin
    24.02.2019 17:56

    На чем запускались бенчмарки?


    1. MWGuy
      24.02.2019 18:01

      AMD FX-8300, Manjaro Linux Gnome


      1. tuxi
        24.02.2019 22:18

        он сопоставим с Intel i5-2540M?


        1. DrPass
          25.02.2019 00:09

          В одноядерном режиме примерно одинаковые по производительности. Но в 8300 ядер в два раза больше.


          1. tuxi
            25.02.2019 00:29

            Тогда я не понимаю, почему пример на этом новом языке так медленно работает. Речь в примере про умножение счетчика в цикле и присвоении результата переменной? Я сделал аналогичный тест на java 7, чтобы исключить оптимизацию, внутри цикла поставил присвоение результата переменной и второй строкой сохранял в массив Long.
            6 секунд работал тест, точнее 6 537 093 784 nanoseconds


            1. MWGuy
              25.02.2019 00:39

              Он просто в статье написал цифры от работы с IO. А так если запустить этот код будет примерно 0.5 сек на loli, и 0.04 на C


              1. tuxi
                25.02.2019 01:14

                без массива (то есть как в примере) получается 2688931 nanoseconds или грубо ~3ms


  1. wxmaper
    24.02.2019 18:05
    +7

    разница в производительности двух довольно популярных языков

    Эм. Нет слов.


  1. dev96
    24.02.2019 18:06
    +3

    Зачем вы пишите такой ужасный НЕ C++ код и подписываете его, как C++?
    Ведь люди потом ходят и рассказывают, что C++ страшное и не логичное дерьмо…

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


    1. MWGuy
      24.02.2019 18:16

      Я говорил автору то что это C, но для него что C что C++ одно и тоже…


      1. FlightBlaze Автор
        24.02.2019 18:16
        +7

        Автор вообще дебил


        1. Igor_O
          24.02.2019 22:02

          НЛО сегодня в отпуске?..
          Вы можете как-то обосновать свое утверждение? Ну, там, не знаю..., показать ошибки в коде?
          Привести пример более корректно написанного кода?
          Популярно объяснить, чем именно плох язык loli? (кроме проблем с поиском из-за того, что интернет — это про… про другое… Я однажды в 2010-м пытался найти Poron. Есть такой материал. Микропористый полиуретан. Удивительное свойство — после сжатия в течение многих лет восстанавливает форму. Идеальный материал для уплотнителей, которые не должны держать больших перепадов давления, но должны жить в условиях изменяющегося зазора… Я сломался на, кажется, 300-какой-то странице поисковой выдачи… Что забавно, гугль кто-то взломал. И вот прямо сейчас по запросу «poron» первые несколько страниц выдачи — про микропористый полиуретан. И никаких намеков на опечатку в слове «porn»… Но Яндекс — продолжает упорствовать… Только хардкор. Варианты с микропористой резиной — не расматриваются...)


          1. DrPass
            24.02.2019 22:04
            +3

            Вы можете как-то обосновать свое утверждение? Ну, там, не знаю..., показать ошибки в коде?

            Я думаю, господин FlightBlaze с автором статьи сам договорится, без вашей помощи. Не вмешивайтесь в их диалог.


      1. dev96
        24.02.2019 18:21

        Попросили бы тогда кого-нибудь другого написать пример.
        А этот — это просто…

        Ощущение, будто пример на якобы C++ намеренно так грязно и тупо написан, когда в loli все так минималистично.

        Плюс: есть ошибки.
        И к чему здесь потоки? И время в loli замеряется с учетом создания потока.


  1. 0xf0a00
    24.02.2019 19:36
    +1

    Я конечно очень извиняюсь, но кто то мультиков пересмотрел?


    1. MWGuy
      24.02.2019 19:43
      +2

      Аниме не мультики!


  1. zim32
    24.02.2019 19:45
    +4

    Думаю этот язык займет свою нишу. А потом их всех посадят


  1. daiver19
    24.02.2019 20:07
    +7

    Поздравляю, вы сравнили скорость записи в консоль на двух языках.


  1. Heian
    24.02.2019 21:48
    +5

    Вместо thrown нужно использовать ключевое слово baka, а вместо threads tentacles. Вместо parent sempai, и так далее. Замечательный язык будет, найдет свою нишу и будет самобытен.


    1. DrPass
      24.02.2019 22:05
      +2

      Да, а вместо исключений оно должно смущённо говорить «ня».


    1. MonkAlex
      24.02.2019 22:11
      +1

      Хм, а это довольно упорото и забавно.
      Надо тогда ещё каких-нибудь типичных фраз надобавлять, которые будут компиляться.
      Типа, baka hentai ~ yossya ~ iku zo ~ zettai yurusenai (контекст бы ещё придумать к этому :D)


      1. Sirikid
        25.02.2019 02:05

        Вместо segmentation violation будет «не туда, семпай»


      1. Nexon
        25.02.2019 07:16

        После чего переименовать язык в LOLi и всё встанет на свои места.


      1. Misaka10032
        25.02.2019 08:17

        Хм, а в C такое делается с помощью #define. Интересно, а тут есть препроцессор? Если нет — надо добавить :D


        1. MWGuy
          25.02.2019 11:36

          он в планах


  1. Electrohedgehog
    25.02.2019 07:49

    Выполнил в консоли браузера:

    var t = Date.now();
    for (var i=0;  i<10000000; i ++){
      var e = i * i;
    }
    console.log('Cycle finished in ' + (Date.now()-t)  +' ms');


    Судя по результатам, Javascript быстрее C++* примерно в 1600 раз. Шах и мат!

    * — C++ автора статьи. Может отличаться от общепринятого С++. Возможны противопоказания. Перед применением проконсультируйтесь со специалистом.


  1. willmore
    25.02.2019 11:17

    За таким многообещающим заголовком надеялся найти обзор языка с примерами и разбором синтаксиса, а получил… это.


    1. MWGuy
      25.02.2019 11:37

      1. willmore
        25.02.2019 12:07

        Спасибо.


  1. funny_falcon
    25.02.2019 11:17

    Очень жаль, что автор взял чужие исходники, и не упомянул откуда. Тем самым, он выдал их за полностью свои, тем самым, совершив акт плагиата: https://github.com/FascinatedBox/lily



  1. zzzmmtt
    25.02.2019 11:57

    Да даже пэхапэ эту лоли уделывает, чо уж там.

    work-machine:~/test$ cat loli_sucks.php 
    <?php
    
    $startTime = microtime();
    
    for($i=1;$i<=10000000;++$i){
       $b = $i*$i;
    }
    
    echo microtime()-$startTime; echo PHP_EOL;
    
    work-machine:~/test$ php loli_sucks.php 
    0.105275
    


  1. Quarc
    25.02.2019 13:05

    8 тысячных секунды на С++.

    > $ cat main.cpp
    #include <iostream>
    #include <chrono>
    #include <thread>
    
    using namespace std;
    
    void thread_fn() {
        int s = 0;
        for (int i = 0; i < 1e6; ++i) {
            s += i * i;
        }
    }
    
    int main()
    {
        chrono::high_resolution_clock::time_point t1 = chrono::high_resolution_clock::now();
    
        std::thread thr(thread_fn);
        thr.join();
    
        chrono::high_resolution_clock::time_point t2 = chrono::high_resolution_clock::now();
        chrono::duration<double> time_int = chrono::duration_cast<chrono::duration<double>>(t2 - t1);
        cout << time_int.count() << "s elapsed\n";
        return 0;
    }
    > $ g++ -std=gnu++17 main.cpp
    
    > $ ./a.out
    0.008097s elapsed
    

    А с О3 так и вообще меньше одной седьмой доли секунды
    > $ g++ -std=gnu++17 -O3 main.cpp
    
    > $ ./a.out
    0.000131s elapsed