ECMAScript и все-все-все — различия между версиями

Материал из YourcmcWiki
Перейти к: навигация, поиск
м
Строка 3: Строка 3:
 
</slideshow>
 
</slideshow>
  
== ECMAScript - ассемблер будущего,<br /> бэкенд, фронтенд и все-все-все @@ %% ==
+
== ECMAScript — ассемблер будущего,<br /> бэкенд, фронтенд и все-все-все @@ %% ==
  
 
''(Об эволюции и фичах JavaScript)''
 
''(Об эволюции и фичах JavaScript)''
Строка 16: Строка 16:
  
 
* Начинал лет в 11 с C/C++ (Turbo C / C++Builder)
 
* Начинал лет в 11 с C/C++ (Turbo C / C++Builder)
* Потом открыл для себя Linux, свободный софт...
+
* Потом открыл для себя Linux, свободный софт…
 
*: ''главное читать логи :)''
 
*: ''главное читать логи :)''
* ...LAMP (Perl/PHP), HTML и JS
+
* …LAMP (Perl/PHP), HTML и JS
 
* Теперь полюбил серверный JS (nodejs)
 
* Теперь полюбил серверный JS (nodejs)
  
Строка 33: Строка 33:
  
 
<s>JavaScript</s>ECMAScript
 
<s>JavaScript</s>ECMAScript
 +
* '''От Java только часть названия'''
 
* Скриптота! (динамический язык)
 
* Скриптота! (динамический язык)
 
* Объект/массив/скаляр (JSON)
 
* Объект/массив/скаляр (JSON)
 
* Прототипы, замыкания, колбэки, нет многопоточности
 
* Прототипы, замыкания, колбэки, нет многопоточности
* ES - язык. А ещё есть окружение (DOM, BOM)
+
* ES — язык. А ещё есть окружение (DOM, BOM)
 
* Куча новых фич (ES2015-2016-2017)
 
* Куча новых фич (ES2015-2016-2017)
* Браузерный - Chrome (V8), Firefox (SpiderMonkey) и даже IE (ChakraCore)
+
* Браузерный — Chrome (V8), Firefox (SpiderMonkey) и даже IE (ChakraCore)
* Серверный - node.js (V8)
+
* Серверный — node.js (V8)
  
 
== Скриптота vs типизация @@ %% ==
 
== Скриптота vs типизация @@ %% ==
Строка 50: Строка 51:
 
* Популярных динамических языков много
 
* Популярных динамических языков много
 
*: {{gray|''можно пытаться это отрицать, но таки удобно''}}
 
*: {{gray|''можно пытаться это отрицать, но таки удобно''}}
* Статические... хде они? Java? (C# не в счёт, винда)
+
* Статические… хде они? Java? (C# не в счёт, винда)
 
* Компилируемые новые есть: D, Rust, Go, Vala, Swift
 
* Компилируемые новые есть: D, Rust, Go, Vala, Swift
 
*: {{gray|''но кто на них пишет-то?''}}
 
*: {{gray|''но кто на них пишет-то?''}}
Строка 56: Строка 57:
 
== Все хотят одного @@ ==
 
== Все хотят одного @@ ==
  
* Типизация - не необходимость, как раньше, а лишь один из способов проверки
+
* Типизация — не необходимость, как раньше, а лишь один из способов проверки
 
*: что ещё можно проверять?
 
*: что ещё можно проверять?
 
*: Rust = borrow checker
 
*: Rust = borrow checker
*: функциональщина = "purity" checker
+
*: функциональщина = «purity» checker
 
* При этом
 
* При этом
 
*: auto уже даже в C++
 
*: auto уже даже в C++
 
*: тайпчекер (частично) уже даже в PHP (+ Hack)
 
*: тайпчекер (частично) уже даже в PHP (+ Hack)
  
== Проверки - хорошо, но @@ %% ==
+
== Проверки — хорошо, но @@ %% ==
  
 
http://demotivators.to/media/posters/327/414874_paranojya.jpg
 
http://demotivators.to/media/posters/327/414874_paranojya.jpg
Строка 71: Строка 72:
  
 
* Нейтральный C-подобный синтаксис
 
* Нейтральный C-подобный синтаксис
* Быстрый!
+
* Быстрый! {{gray|(как вычислительно, так и для I/O)}}
* Событийная машина
+
*: Событийная машина node.js — не пустой звук! {{gray|(1M соединений на одном сервере)}}
*: {{gray|не пустой звук! 1M соединений на одном сервере}}
+
* Всегда нужен в браузерах {{gray|(а веб нынче даже 1С)}}
* Есть тайпчекеры
+
* Мощное сообщество и развитие
*: {{gray|TypeScript, Dart...}}
+
* Удобный пакетный менеджер npm
* Круто развивается
+
* Есть тайпчекеры: TypeScript, Dart…
  
 
== Синтаксис @@ %% ==
 
== Синтаксис @@ %% ==
Строка 169: Строка 170:
 
</source>
 
</source>
  
* projects - переменная? Фигвам. Метод без аргументов.)
+
* projects — переменная? Фигвам. Метод без аргументов.)
  
 
== Go @@ ==
 
== Go @@ ==
Строка 290: Строка 291:
 
}
 
}
 
</source>
 
</source>
 +
 +
== Синтаксис JS @@ %% ==
 +
 +
Имхо вполне нейтральненько.
 +
 +
{{gray|(неприятных рефлексов вызывать не должен)}}
 +
 +
== История JS @@ ==
 +
 +
* 1995—2004: дремучий лес с партизанами
 +
* 2004—2008: появление AJAX
 +
* 2008+: шустрота и современный период
 +
 +
== Дремучий период @@ ==
 +
 +
1995—1997
 +
* Создание и начальная стандартизация
 +
* DOM ещё нет, только «DOM level 0»
 +
*: document.forms, document.images
 +
 +
1998
 +
* DOM level 1 (DHTML)
 +
* document.getElementById, все элементы — объекты
 +
 +
2000
 +
* DOM level 2
 +
* События и более-менее современный вид объектов
 +
* pre-AJAX: JSONP, невидимый iframe
 +
 +
== Появление AJAX @@ ==
 +
 +
2004
 +
* Firefox 1.0
 +
* XmlHttpRequest
 +
* Gmail, впервые упомянут термин «AJAX»
 +
* {{gray|Начало конца дремучего периода JS, как языка для всплывающих баннеров}}
 +
 +
Совместимость браузеров ещё плохая, так что
 +
* 2006 — jQuery
 +
 +
== Современное развитие @@ ==
 +
 +
* 2008 — Google V8
 +
* 2009 — IE8 (M$ очнулся)
 +
* 2009 — node.js (2011 — v0.6)
 +
* 2011 — начало работы над ES6
 +
* 2012 — Angular 1.0
 +
* 2013 — React
 +
* 2015 — ES6 принят
 +
 +
== Производительность @@ ==
 +
 +
На ЛОРе до сих пор шутят, что «Java тормозит», а что ж тогда JS?
 +
* А ничего — он быстрый.
 +
* Но он же интерпретируемый?
 +
*: НЕТ! '''Интерпретируемых''' языков уже вообще нет.
 +
*: <s>Ну, разве что bash…</s>
 +
 +
== Вычислительный [https://blog.famzah.net/2016/02/09/cpp-vs-python-vs-perl-vs-php-performance-benchmark-2016/ бенчмарк] @@ ==
 +
 +
* C++ (g++ 5.3.1) -O2 = 1.124s
 +
* java8 = 1.428s
 +
* PyPy (tracing jit) = 1.72s
 +
* '''node.js = 2s'''
 +
* java7 = ~2.5s
 +
* PHP 7 = 6.7s
 +
* Python 3.5 = 19s, 2.7 = 21s
 +
* Perl = 25s
 +
* '''PHP 5.6 = 69s''' :)))))
 +
 +
== Почему V8 такой быстрый? @@ ==
 +
 +
Потому, что 4-слойный JIT!
 +
* {{gray|Как уже сказано, интерпретируемых языков нет.}}
 +
* 1 слой - LLInt, интерпретатор байткода (быстрый старт)
 +
* 2 слой - Baseline JIT
 +
* 3 слой - DFG (Data Flow Graph) JIT
 +
* 4 слой - <s>LLVM</s> [https://webkit.org/blog/5852/introducing-the-b3-jit-compiler/ B3]
 +
 +
https://webkit.org/blog-files/ftl-jit/four_tier_performance.png
 +
 +
== Ключевые слова о том, как это всё устроено @@ ==
 +
 +
* Какой бывает JIT?
 +
*: method-based jit (JVM)
 +
*: tracing jit (PyPy, TraceMonkey)
 +
* Девиртуализация
 +
* Ускорение поиска в хеше (Lua)
 +
* OSR (On-Stack Replace)
 +
 +
== Отступление: PyPy @@ %% ==
 +
 +
Трассирующий JIT-компилятор для Python, очень медленный
 +
 +
Рисует множество Мандельброта при сборке
 +
 +
http://gyazo.com/2c32601f8747c5e93becc08270fa5127.png
 +
 +
== LLVM @@ ==
 +
 +
[[Файл:LLVM Logo.svg|200px|right]]
 +
LLVM (http://llvm.org), ранее "Low Level Virtual Machine"
 +
* Набор библиотек для построения компиляторов/интерпретаторов
 +
* Модульный
 +
*: исходник &rarr; фронтенд (ЯП) &rarr; LLVM IR (SSA)
 +
*: IR &rarr; оптимизатор LLVM &rarr; IR
 +
*: IR &rarr; бэкенд &rarr; машинный код
 +
* А также сами компиляторы (в первую очередь C/C++/ObjC: Clang)
 +
* {{gray|На LLVM сделаны компилятор шейдеров Radeon и OpenCL}}
 +
 +
http://www.aosabook.org/images/llvm/LLVMCompiler1.png
 +
 +
== V8 JIT @@ ==
 +
 +
[https://webkit.org/blog/3362/introducing-the-webkit-ftl-jit/ FTL JIT]
 +
* Первый раз функции запускаются в LLInt
 +
* 6 вызовов либо 100 повторов строки
 +
*: {{green|&rarr; OSR в Baseline JIT}}
 +
* 66 вызовов либо 1000*C повторов строки
 +
*: {{green|&rarr; OSR в DFG JIT}}
 +
*: C ~ 1, больше для больших функций
 +
* Нарушение type guard в DFG
 +
*: {{red|&rarr; OSR обратно в Baseline JIT}}
 +
* 6666 вызовов либо 100000*C повторов строки
 +
*: {{green|&rarr; OSR в LLVM/B3 JIT}}
  
 
[[Категория:VitaliPrivate]]
 
[[Категория:VitaliPrivate]]

Версия 15:19, 10 октября 2016

Автор

Виталий Филиппов
Дополнительный нижний колонтитул

ECMAScript и все-все-все

ECMAScript — ассемблер будущего,
бэкенд, фронтенд и все-все-все @@ %%

(Об эволюции и фичах JavaScript)

ES6.jpg

Виталий Филиппов, CUSTIS

О своих предпочтениях @@

«И давно вы занимаетесь программизмом?»

  • Начинал лет в 11 с C/C++ (Turbo C / C++Builder)
  • Потом открыл для себя Linux, свободный софт…
    главное читать логи :)
  • …LAMP (Perl/PHP), HTML и JS
  • Теперь полюбил серверный JS (nodejs)

О чём доклад? @@

  • Почему JS?
  • История JavaScript
  • Обзор языка, производительность
  • Обзор выдумок
    (фреймворки, системы сборки и т.п)
  • Немного демо

Что такое JS? @@

JavaScriptECMAScript

  • От Java только часть названия
  • Скриптота! (динамический язык)
  • Объект/массив/скаляр (JSON)
  • Прототипы, замыкания, колбэки, нет многопоточности
  • ES — язык. А ещё есть окружение (DOM, BOM)
  • Куча новых фич (ES2015-2016-2017)
  • Браузерный — Chrome (V8), Firefox (SpiderMonkey) и даже IE (ChakraCore)
  • Серверный — node.js (V8)

Скриптота vs типизация @@ %%

script_kiddies_demotivator.jpeg

Холивар!!! @@

  • Шутки в сторону: тема серьёзная
  • Популярных динамических языков много
    можно пытаться это отрицать, но таки удобно
  • Статические… хде они? Java? (C# не в счёт, винда)
  • Компилируемые новые есть: D, Rust, Go, Vala, Swift
    но кто на них пишет-то?

Все хотят одного @@

  • Типизация — не необходимость, как раньше, а лишь один из способов проверки
    что ещё можно проверять?
    Rust = borrow checker
    функциональщина = «purity» checker
  • При этом
    auto уже даже в C++
    тайпчекер (частично) уже даже в PHP (+ Hack)

Проверки — хорошо, но @@ %%

414874_paranojya.jpg

Почему JS? @@

  • Нейтральный C-подобный синтаксис
  • Быстрый! (как вычислительно, так и для I/O)
    Событийная машина node.js — не пустой звук! (1M соединений на одном сервере)
  • Всегда нужен в браузерах (а веб нынче даже 1С)
  • Мощное сообщество и развитие
  • Удобный пакетный менеджер npm
  • Есть тайпчекеры: TypeScript, Dart…

Синтаксис @@ %%

Perl @@

sub _skip_attrs
{
    my ($tag, $attrs) = @_;
    $tag = lc $tag;
    return "<$tag>" if $tag =~ m!^/!so;
    my ($enclosed) = $attrs =~ m!/$!so ? ' /' : '';
    $attrs = { $attrs =~ /([^\s=]+)=([^\s=\'\"]+|\"[^\"]*\"|\'[^\']*\')/gso };
    my $new = {};
    for (qw(name id class style title))
    {
        $new->{$_} = $attrs->{$_} if $attrs->{$_};
    }
    my %l = (a => 'href', blockquote => 'cite', q => 'cite');
    if ($attrs->{$l{$tag}} && $attrs->{$l{$tag}} !~ /^[\"\']?javascript/iso)
    {
        $new->{$l{$tag}} = $attrs->{$l{$tag}};
    }
    return "<$tag".join("", map { " $_=".$new->{$_} } keys %$new).$enclosed.">";
}
  • Спецсимволы захватили мир

PHP @@

$isExact = [];
foreach ([ 'line' => 'l', 'cfo' => 'cc' ] as $k => $t)
{
    if (!isset($specified[$k.'_id']) && !isset($specified[$k.'_id_exact']) && 
        !isset($groups[$k]) && !isset($groups[$k.'_all']))
        $isExact[] = "$posAlias.${k}_id IS NULL";
    elseif ($lastgrp == $k.'all')
        $isExact[] = "$posAlias.${k}_id=$t.id";
}
foreach ([ 'party', 'account', 'paytype' ] as $k)
    if (!isset($specified[$k.'_id']) && !isset($groups[$k]))
        $isExact[] = "$posAlias.${k}_id IS NULL";
return implode(' AND ', $isExact) ?: '1=1';
  • Что за $$$$$?

Python @@

class FileCache:
  def __init__(self, dir):
    self.dir = dir
    if not os.path.isdir(dir):
      os.mkdir(dir)
  def fn(self, key):
    key = re.sub('([^a-zA-Z0-9_\-]+)', lambda x: binascii.hexlify(x.group(1)), key)
    return self.dir+'/'+key
  def clean(self):
    t = time.time()
    for fn in os.listdir(self.dir):
      if t > os.stat(self.dir+'/'+fn).st_mtime:
        os.unlink(self.dir+'/'+fn)
  • Пробелы меняют смысл?!!!!

Ruby @@

module Gitlab
  class SearchResults
    attr_reader :current_user, :query
 
    def objects(scope, page = nil)
      case scope
      when 'projects'
        projects.page(page).per(per_page)
      when 'issues'
        issues.page(page).per(per_page)
      when 'merge_requests'
        merge_requests.page(page).per(per_page)
      when 'milestones'
        milestones.page(page).per(per_page)
      else
        Kaminari.paginate_array([]).page(page).per(per_page)
      end
    end
  • projects — переменная? Фигвам. Метод без аргументов.)

Go @@

func TestChannelStoreSave(t *testing.T) {
        Setup()
 
        teamId := model.NewId()
 
        o1 := model.Channel{}
        o1.TeamId = teamId
        o1.DisplayName = "Name"
        o1.Name = "a" + model.NewId() + "b"
        o1.Type = model.CHANNEL_OPEN
 
        if err := (<-store.Channel().Save(&o1)).Err; err != nil {
                t.Fatal("couldn't save item", err)
        }
 
        if err := (<-store.Channel().Save(&o1)).Err; err == nil {
                t.Fatal("shouldn't be able to update from save")
        }
  • Что за смайлики := <- & *? Где мои скобочки?

Erlang @@

iq_handler(From, _To,
	   #iq{type=set, lang = Lang,
	       sub_el = #xmlel{name = Operation} = SubEl} = IQ, CC)->
    ?DEBUG("carbons IQ received: ~p", [IQ]),
    {U, S, R} = jid:tolower(From),
    Result = case Operation of
        <<"enable">>->
	    ?INFO_MSG("carbons enabled for user ~s@~s/~s", [U,S,R]),
            enable(S,U,R,CC);
        <<"disable">>->
	    ?INFO_MSG("carbons disabled for user ~s@~s/~s", [U,S,R]),
            disable(S, U, R)
    end,
    case Result of
        ok ->
	    ?DEBUG("carbons IQ result: ok", []),
            IQ#iq{type=result, sub_el=[]};
	{error,_Error} ->
	    ?ERROR_MSG("Error enabling / disabling carbons: ~p", [Result]),
	    Txt = <<"Database failure">>,
            IQ#iq{type=error,sub_el = [SubEl, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)]}
end;
  • Ой-ой-ой
  • Классов нет, есть процессы

OCaml O_O @@

let log_client_info c sock = 
  let buf = Buffer.create 100 in
  let date = BasicSocket.date_of_int (last_time ()) in
  Printf.bprintf buf "%-12s(%d):%d -> %-30s[%-14s %-20s] connected for %5d secs %-10s bw %5d/%-5d %-6s %2d/%-2d reqs " 
    (Date.simple date) 
  (nb_sockets ())
  (client_num c)
  (
    let s = c.client_name in
    let len = String.length s in 
    if len > 30 then String.sub s 0 30 else s)
 
  (brand_to_string c.client_brand)
  (match c.client_kind with Indirect_address _ | Invalid_address _ -> "LowID"
    | Direct_address (ip,port) -> Printf.sprintf "%s:%d"
          (Ip.to_string ip) port)
  (last_time () - c.client_connect_time)
  (if c.client_rank > 0 then
      Printf.sprintf "rank %d" c.client_rank
      else "")
  (nwritten sock) (nread sock)
  (if c.client_banned then "banned" else "")
  c.client_requests_received
    c.client_requests_sent
  ;
  • ПОЛИЗ?!!!!

JS @@

TreeGridNode.prototype.setChildren = function(isLeaf, newChildren)
{
    if (!this.tr)
        this.grid.tbody.innerHTML = '';
    else
    {
        var tr = this.tr[this.tr.length-1];
        while (tr.nextSibling && tr.nextSibling._node.level > this.level)
            this.grid.tbody.removeChild(tr.nextSibling);
        if (this.leaf != isLeaf)
        {
            if (isLeaf)
            {
                this.tr[0].cells[0].firstChild.className = 'collapser collapser-inactive';
                removeListener(this.tr[0].cells[0].firstChild, 'click', this._getToggleHandler());
            }
            else
            {
                this.tr[0].cells[0].firstChild.className = this.collapsed ? 'collapser collapser-collapsed' : 'collapser collapser-expanded';
                addListener(this.tr[0].cells[0].firstChild, 'click', this._getToggleHandler());
            }
        }
    }
    this.leaf = isLeaf;
    this.children = [];
    this.childrenByKey = {};
    this.addChildren(newChildren);
}

Синтаксис JS @@ %%

Имхо вполне нейтральненько.

(неприятных рефлексов вызывать не должен)

История JS @@

  • 1995—2004: дремучий лес с партизанами
  • 2004—2008: появление AJAX
  • 2008+: шустрота и современный период

Дремучий период @@

1995—1997

  • Создание и начальная стандартизация
  • DOM ещё нет, только «DOM level 0»
    document.forms, document.images

1998

  • DOM level 1 (DHTML)
  • document.getElementById, все элементы — объекты

2000

  • DOM level 2
  • События и более-менее современный вид объектов
  • pre-AJAX: JSONP, невидимый iframe

Появление AJAX @@

2004

  • Firefox 1.0
  • XmlHttpRequest
  • Gmail, впервые упомянут термин «AJAX»
  • Начало конца дремучего периода JS, как языка для всплывающих баннеров

Совместимость браузеров ещё плохая, так что

  • 2006 — jQuery

Современное развитие @@

  • 2008 — Google V8
  • 2009 — IE8 (M$ очнулся)
  • 2009 — node.js (2011 — v0.6)
  • 2011 — начало работы над ES6
  • 2012 — Angular 1.0
  • 2013 — React
  • 2015 — ES6 принят

Производительность @@

На ЛОРе до сих пор шутят, что «Java тормозит», а что ж тогда JS?

  • А ничего — он быстрый.
  • Но он же интерпретируемый?
    НЕТ! Интерпретируемых языков уже вообще нет.
    Ну, разве что bash…

Вычислительный бенчмарк @@

  • C++ (g++ 5.3.1) -O2 = 1.124s
  • java8 = 1.428s
  • PyPy (tracing jit) = 1.72s
  • node.js = 2s
  • java7 = ~2.5s
  • PHP 7 = 6.7s
  • Python 3.5 = 19s, 2.7 = 21s
  • Perl = 25s
  • PHP 5.6 = 69s :)))))

Почему V8 такой быстрый? @@

Потому, что 4-слойный JIT!

  • Как уже сказано, интерпретируемых языков нет.
  • 1 слой - LLInt, интерпретатор байткода (быстрый старт)
  • 2 слой - Baseline JIT
  • 3 слой - DFG (Data Flow Graph) JIT
  • 4 слой - LLVM B3

four_tier_performance.png

Ключевые слова о том, как это всё устроено @@

  • Какой бывает JIT?
    method-based jit (JVM)
    tracing jit (PyPy, TraceMonkey)
  • Девиртуализация
  • Ускорение поиска в хеше (Lua)
  • OSR (On-Stack Replace)

Отступление: PyPy @@ %%

Трассирующий JIT-компилятор для Python, очень медленный

Рисует множество Мандельброта при сборке

2c32601f8747c5e93becc08270fa5127.png

LLVM @@

LLVM Logo.svg

LLVM (http://llvm.org), ранее "Low Level Virtual Machine"

  • Набор библиотек для построения компиляторов/интерпретаторов
  • Модульный
    исходник → фронтенд (ЯП) → LLVM IR (SSA)
    IR → оптимизатор LLVM → IR
    IR → бэкенд → машинный код
  • А также сами компиляторы (в первую очередь C/C++/ObjC: Clang)
  • На LLVM сделаны компилятор шейдеров Radeon и OpenCL

LLVMCompiler1.png

V8 JIT @@

FTL JIT

  • Первый раз функции запускаются в LLInt
  • 6 вызовов либо 100 повторов строки
    → OSR в Baseline JIT
  • 66 вызовов либо 1000*C повторов строки
    → OSR в DFG JIT
    C ~ 1, больше для больших функций
  • Нарушение type guard в DFG
    → OSR обратно в Baseline JIT
  • 6666 вызовов либо 100000*C повторов строки
    → OSR в LLVM/B3 JIT