ECMAScript и все-все-все — различия между версиями
Материал из YourcmcWiki
м |
|||
Строка 3: | Строка 3: | ||
</slideshow> | </slideshow> | ||
− | == | + | == 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 |
* Теперь полюбил серверный JS (nodejs) | * Теперь полюбил серверный JS (nodejs) | ||
Строка 33: | Строка 33: | ||
<s>JavaScript</s>ECMAScript | <s>JavaScript</s>ECMAScript | ||
+ | * '''От Java только часть названия''' | ||
* Скриптота! (динамический язык) | * Скриптота! (динамический язык) | ||
* Объект/массив/скаляр (JSON) | * Объект/массив/скаляр (JSON) | ||
* Прототипы, замыкания, колбэки, нет многопоточности | * Прототипы, замыкания, колбэки, нет многопоточности | ||
− | * | + | * ES — язык. А ещё есть окружение (DOM, BOM) |
* Куча новых фич (ES2015-2016-2017) | * Куча новых фич (ES2015-2016-2017) | ||
− | * | + | * Браузерный — Chrome (V8), Firefox (SpiderMonkey) и даже IE (ChakraCore) |
− | * | + | * Серверный — node.js (V8) |
== Скриптота vs типизация @@ %% == | == Скриптота vs типизация @@ %% == | ||
Строка 50: | Строка 51: | ||
* Популярных динамических языков много | * Популярных динамических языков много | ||
*: {{gray|''можно пытаться это отрицать, но таки удобно''}} | *: {{gray|''можно пытаться это отрицать, но таки удобно''}} | ||
− | * | + | * Статические… хде они? Java? (C# не в счёт, винда) |
* Компилируемые новые есть: D, Rust, Go, Vala, Swift | * Компилируемые новые есть: D, Rust, Go, Vala, Swift | ||
*: {{gray|''но кто на них пишет-то?''}} | *: {{gray|''но кто на них пишет-то?''}} | ||
Строка 56: | Строка 57: | ||
== Все хотят одного @@ == | == Все хотят одного @@ == | ||
− | * | + | * Типизация — не необходимость, как раньше, а лишь один из способов проверки |
*: что ещё можно проверять? | *: что ещё можно проверять? | ||
*: Rust = borrow checker | *: Rust = borrow 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|(а веб нынче даже 1С)}} | |
− | * | + | * Мощное сообщество и развитие |
− | + | * Удобный пакетный менеджер npm | |
− | * | + | * Есть тайпчекеры: TypeScript, Dart… |
== Синтаксис @@ %% == | == Синтаксис @@ %% == | ||
Строка 169: | Строка 170: | ||
</source> | </source> | ||
− | * | + | * 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" | ||
+ | * Набор библиотек для построения компиляторов/интерпретаторов | ||
+ | * Модульный | ||
+ | *: исходник → фронтенд (ЯП) → LLVM IR (SSA) | ||
+ | *: IR → оптимизатор LLVM → IR | ||
+ | *: IR → бэкенд → машинный код | ||
+ | * А также сами компиляторы (в первую очередь 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|→ OSR в Baseline JIT}} | ||
+ | * 66 вызовов либо 1000*C повторов строки | ||
+ | *: {{green|→ OSR в DFG JIT}} | ||
+ | *: C ~ 1, больше для больших функций | ||
+ | * Нарушение type guard в DFG | ||
+ | *: {{red|→ OSR обратно в Baseline JIT}} | ||
+ | * 6666 вызовов либо 100000*C повторов строки | ||
+ | *: {{green|→ OSR в LLVM/B3 JIT}} | ||
[[Категория:VitaliPrivate]] | [[Категория:VitaliPrivate]] |
Версия 15:19, 10 октября 2016
- Автор
- Виталий Филиппов
- Дополнительный нижний колонтитул
- ECMAScript и все-все-все
Содержание
- 1 ECMAScript — ассемблер будущего, бэкенд, фронтенд и все-все-все @@ %%
- 2 О своих предпочтениях @@
- 3 О чём доклад? @@
- 4 Что такое JS? @@
- 5 Скриптота vs типизация @@ %%
- 6 Холивар!!! @@
- 7 Все хотят одного @@
- 8 Проверки — хорошо, но @@ %%
- 9 Почему JS? @@
- 10 Синтаксис @@ %%
- 11 Perl @@
- 12 PHP @@
- 13 Python @@
- 14 Ruby @@
- 15 Go @@
- 16 Erlang @@
- 17 OCaml O_O @@
- 18 JS @@
- 19 Синтаксис JS @@ %%
- 20 История JS @@
- 21 Дремучий период @@
- 22 Появление AJAX @@
- 23 Современное развитие @@
- 24 Производительность @@
- 25 Вычислительный бенчмарк @@
- 26 Почему V8 такой быстрый? @@
- 27 Ключевые слова о том, как это всё устроено @@
- 28 Отступление: PyPy @@ %%
- 29 LLVM @@
- 30 V8 JIT @@
ECMAScript — ассемблер будущего,
бэкенд, фронтенд и все-все-все @@ %%
(Об эволюции и фичах JavaScript)
Виталий Филиппов, 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 типизация @@ %%
Холивар!!! @@
- Шутки в сторону: тема серьёзная
- Популярных динамических языков много
- можно пытаться это отрицать, но таки удобно
- Статические… хде они? Java? (C# не в счёт, винда)
- Компилируемые новые есть: D, Rust, Go, Vala, Swift
- но кто на них пишет-то?
Все хотят одного @@
- Типизация — не необходимость, как раньше, а лишь один из способов проверки
- что ещё можно проверять?
- Rust = borrow checker
- функциональщина = «purity» checker
- При этом
- auto уже даже в C++
- тайпчекер (частично) уже даже в PHP (+ Hack)
Проверки — хорошо, но @@ %%
Почему 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 слой -
LLVMB3
Ключевые слова о том, как это всё устроено @@
- Какой бывает JIT?
- method-based jit (JVM)
- tracing jit (PyPy, TraceMonkey)
- Девиртуализация
- Ускорение поиска в хеше (Lua)
- OSR (On-Stack Replace)
Отступление: PyPy @@ %%
Трассирующий JIT-компилятор для Python, очень медленный
Рисует множество Мандельброта при сборке
LLVM @@
LLVM (http://llvm.org), ранее "Low Level Virtual Machine"
- Набор библиотек для построения компиляторов/интерпретаторов
- Модульный
- исходник → фронтенд (ЯП) → LLVM IR (SSA)
- IR → оптимизатор LLVM → IR
- IR → бэкенд → машинный код
- А также сами компиляторы (в первую очередь C/C++/ObjC: Clang)
- На LLVM сделаны компилятор шейдеров Radeon и OpenCL
V8 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