Three.js: Принять некоторые функции ES6

Созданный на 16 апр. 2015  ·  74Комментарии  ·  Источник: mrdoob/three.js

Скоро появится ES6, и браузеры и инструменты теперь быстро получают поддержку. Я думаю, THREE.js может извлечь огромную пользу из некоторых новых функций, представленных ES6.

Для развлечения и для поощрения дебатов по поводу возможной миграции проекта я создал эту задачу и создал несколько примеров кода.

Возможности, продемонстрированные в примерах ниже:

  • Параметры по умолчанию
  • let ключевое слово с ограниченной областью видимости
  • Итераторы + For..Of
  • Классы
  • Стрелочные функции
  • Генераторы
  • Модули

Пример класса

import Object3D from '../core/Object3D';
import Geometry from '../core/Geometry';
import MeshBasicMaterial from '../materials/MeshBasicMaterial';

class Mesh extends Object3D {
    constructor(
        geometry = new Geometry(),
        material = new MeshBasicMaterial({color: Math.random() * 0xffffff}
    ) {
        super();

        this.geometry = geometry;
        this.material = material;

        this.updateMorphTargets();
    }
}

export default Mesh;

Пример генератора обхода

class Object3D {
    constructor() {
        ...
    }

    traverse(callback) {
        callback(this);

        for (let object of this.children) {
            object.traverse(callback);
        }
    },

    *traversalGenerator() {
        this.traverse(object => yield object);
    }

    ...
}

Используемый генератор:

for (let object of scene.traversalGenerator()) {
    if (object.name === 'Blah') {
        break;
    }
}

Примечание: я не тестировал ничего из этого

Suggestion

Самый полезный комментарий

https://github.com/mrdoob/three.js/commit/1017a5432eede4487436d6d34807fda24b506088

Хорошо, я думаю, мы можем начать с let и const в src/ .

@DefinitoMaybe. Вы хотели бы помочь с этим?

Все 74 Комментарий

Наверное, рано? Поддержка кроссбраузерности не всегда велика: http://kangax.github.io/compat-table/es6/

let не отображается в FF и не в 100% случаев в Chrome и IE.
generators недоступно в IE
class есть только в Chrome, техническом предварительном просмотре IE12 (Spartan) для Win10 и FF39, который на две версии выше текущей.
import пока недоступен
super доступен только в IE12, но не в IE11, Chrome или FF.
arrow functions нет в IE11 или Chrome

Также оба генератора и for-of являются убийцами оптимизации для Chrome.

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

Я немного опоздал на вечеринку ES6. Мне это кажется другим языком. Я регулярно работаю над Three.js, но если бы это выглядело как приведенные выше фрагменты, я не знаю, продолжу ли я. У меня просто не хватает терпения изучать другую версию JavaScript, которая выглядит по-другому и по-другому функционирует, которая в основном делает то же самое, что и new function () и object.prototype, но, возможно, медленнее.

Это то, чего веб-сообщество требовало от языкового комитета ES6? Я кодирую уже 20 лет, и слово «класс» нигде в моих проектах не встречается (и никогда не появится, если у меня будет свой путь). Откровенно говоря, JavaScript начинает выглядеть как JAVA ... (скрипт). : - \

Я с @benaadams и @jonnenauha ; слишком рано, и это может замедлить код, если Chrome и Firefox не будут сильно оптимизировать эту новую версию языка, как будто они уже оптимизируют JavaScript под капотом (V8 и т. д.).

: +1:

@erichlof Ну, на самом деле я жду больше всего поддержки классов и модулей ES6. В настоящее время я использую AMD для своих приложений. Основной проект JS, над которым я работаю, - это ~ 10 тыс. Строк с сотнями «классов», а AMD - спаситель. Как во время разработки, так и при производстве сборок. Imo, большие или даже меньшие проекты должны иметь какую-то модульную систему и способ декларировать, от чего они зависят. Когда у вас сложная структура проекта, управлять им становится слишком сложно. Программисту не следует выяснять, в каком порядке ставить 25 тегов <script> . Это просто глупо, если у вас есть такое количество файлов, как у three.js. Большинство проектов решают эту проблему, создавая один большой файл js (например, three.js), а затем есть случайные папки дополнений / помощников, в которые вы можете включать другие вещи. Это несколько ограничивает, и я должен включить (минифицированную) сборку ~ 500 КБ, чтобы получить ~ все под солнцем.

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

У вас может не быть «класса» в ваших проектах, но если вы используете object.prototype (как в случае с three.js), это фактически то же самое, вы согласны? Нам нравится соединять предметы и придавать им цель. Затем другой код хочет использовать указанные объекты и чистый декларативный способ их импорта.

Все, что я говорю, классы и модули ES6 были бы хорошим дополнением к three.js, чтобы придать ему больше структуры и модульности для сборок. Это слишком рано, потому что нет поддержки браузеров, например. модулей пока нет. Другие могут сказать, что стоит просто начать их использовать, использовать babel и т. Д. И выводить сборки, совместимые с ES5, я не уверен, что это хорошая идея, но кто знает. Это усложняет разработку, вам нужно автоматически запускать сборку при сохранении файлов, и отладка также может стать более сложной. Я склонен думать, что только ради этих вещей эти транспилеры не стоят того.

PS Это не была напыщенная речь против three.js, просто говорилось, что в ES6 могут быть преимущества для таких проектов, как three.js, если появится поддержка браузера :) и в основном это больше синтаксического сахара, чем создание совершенно нового языка. Просто там будет больше вещей.

Еще одна функция, которая может быть полезна для three.js, - это WeakMap и, возможно, WeakSet . Я не уверен в последствиях, но похоже, что это можно было бы использовать для отслеживания вещей, не заставляя GC выполнять свою работу, если «владелец» больше не владеет ссылкой. В three.js много таких состояний, и их внутреннее использование может иметь значение. Мне кажется, что это немного похоже на общие / слабые ptrs в C ++ на объявление владения.

Хорошим кандидатом могут быть такие вещи, как https://github.com/mrdoob/three.js/blob/master/src/lights/SpotLight.js#L12, где это может быть слабая ссылка и будет автоматически очищена, если цель была сняли с места происшествия и собрали. Но я предполагаю, что вы в любом случае не можете зависеть от коллекции, но в любом случае вам нужно будет обнулить это, как только цель будет удалена со сцены.

Кто знает, я подожду, пока эксперты напишут несколько сообщений в блогах, как все эти функции могут принести пользу приложениям в целом :)

Привет @jonnenauha!

Да, я согласен, что новые функции, такие как «импорт» и «экспорт», будут полезны, особенно в том, что касается модульности. Я считаю, что это направление, в котором @coballast и @kumavis пытаются сделать THREE.js более модульным и управляемым для пользовательских сборок и поддержки кода. Я сторонник модулей и повторного использования объектов и функций, особенно когда у нас есть большой формат библиотеки, такой как THREE.js.

Однако я не думаю, что нам нужен дополнительный синтаксический сахар классов, super, let, for, of, стрелочных функций и т. Д., Когда мы в основном получаем те же функции в JavaScript, которые используются десятилетиями и имеют уже много тяги. Я могу быть устаревшим, но я с Дугласом Крокфордом, когда он говорит, что JavaScript уже является объектно-ориентированным языком (что означает функции = объекты = граждане первого класса), но не «классическим», поэтому нам не следует беспокоиться о вставка классов в JavaScript. Он был разработан с другим подходом - подходом, который меня сначала ошеломил (пришедший из программирования на C / C ++ в 1990-х годах), но с которым я соглашаюсь все больше и больше каждый раз, когда сажусь за код или пытаюсь решить архитектуру кода. проблемы.

Вместо синтаксических изменений в THREE.js я бы предпочел переход к таким функциям, как новый интерфейс программирования SIMD. Я думаю, что ВСЕ математические коды THREE (особенно Vector3 и Matrix4) могут извлечь из этого большую пользу. Вот ссылка на видео (посмотрите 22:51 во временном коде):
https://youtu.be/CbMXkbqQBcQ?t=1371
Когда эта функция появится в основных браузерах, в результате каждый пользователь THREE.js увидит заметное увеличение частоты кадров.

Извините, если мой предыдущий пост прозвучал как напыщенная речь, мне просто нравится THREE.js, как он выглядит сейчас - я могу легко выбрать любую его случайную часть и знать, что происходит, откуда она взялась и что она использует. :)

@erichlof @jonnenauha Я чувствую себя обязанным указать, что классы es6 - это просто сахар, и они внутренне используют механизм прототипов для реализации всего во время выполнения.

Я довольно оптимистичен, что функции es6 не повлияют на производительность вычислений. Модули es6 могут повлиять на время загрузки, когда они, наконец, будут реализованы движками, потому что вы загружаете кучу маленьких файлов, а не один большой файл. HTTP / 2 может сделать это не проблемой. В любом случае, если мы используем модули es6, мы можем использовать browserify для создания пакета, как мы всегда это делаем.

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

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

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

Я бы посоветовал всем, кто интересуется es6, присоединиться и внести свой вклад в это репо: https://github.com/5to6/5to6

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

Например, слабые карты - это то, что было бы огромным преимуществом для средств визуализации для обработки состояний объектов. Его самыми большими недостатками были слабый полифил, очень слабая поддержка браузеров и неизвестные характеристики производительности. (Прошло некоторое время с тех пор, как я исследовал это, так что есть вероятность, что это изменилось)

И мы должны смотреть не только на es6. Например, ams.js отлично подойдет в качестве технологии, запускающей программный рендерер. Для получения дополнительной информации http://stackoverflow.com/questions/18427810/three-and-asmjs/18439786#18439786.

И мы не должны забывать, что большинство участников в основном вносят свой вклад, потому что javascript знаком, а es6 еще не для большинства.

@ gero3 Это хорошие моменты, о которых я не думал. Если мы говорим о микрооптимизации, то я с вами на 100% согласен. Я бы не хотел пользоваться этими функциями без поддержки браузера.

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

ОБНОВИТЬ:
Может, всем плевать, но я передумал. Я считаю, что мы не должны использовать классы. Я все еще думаю, что модули es6 - хорошая идея.

Я полностью за занятия. Я получаю все замечательные вещи, которые может делать прототип объекта в JavaScript. Однако в THREE.js (и во многих других современных проектах ОС) мы используем прототипное наследование для имитации классов, так почему бы не использовать приятную синтаксику и избавиться от таких хакерских вещей, как:

THREE.Object3D.call( this );

а также

THREE.Scene.prototype = Object.create( THREE.Object3D.prototype );

Поскольку классы поддерживаются в стабильных Chrome и Firefox, я бы не стал возражать против обновления кода 😊

Классы @mrdoob поддерживаются в стабильной

Safari на iOS, похоже, сейчас таскает ... 😣

Классы потрясающие, как и другие функции ES7. Мы используем их в одном из наших проектов, но нам пришлось ввести кросс-компилятор (babel.js), потому что нам нужно работать во всех браузерах - Chrome, Firefox, IE и Safari.

Существует преобразование браузера для запуска babel.js (babelify), поэтому оно будет хорошо работать с моими усилиями.

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

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

Насколько я понимаю, ES6 в основном неэффективен и поэтому не предназначен для производства, пока не будет внедрен в браузер. С учетом сказанного, новые проекты или модули должны адаптировать эти удобства сегодня, но при принятии этого решения необходимо учитывать производительность.

Я согласен с @erichlof imo, наиболее полезной реализацией будет SIMD (https://github.com/tc39/ecmascript_simd), даже с использованием полифилла. Похоже, что от этого больше всего выиграют пользователи.

Как SIMD поместится в ThreeJS? Я думаю, что ThreeJS уже перекладывает все важные вычисления на GPU. Хотя я могу отчасти понять, как использовать его в классах Vector, в ThreeJS очень мало математических вычислений, скорее, в основном эти векторы просто транспортируются в GPU.

Я говорю по своему опыту, поскольку раньше реализовывал расширения SSE2 / SSE4 и обнаружил, что в большинстве случаев преимущества были мимолетными - единственными реальными случаями, когда это было преимущество, было то, что у меня были большие массивы, на которых я хотел сделать то же самое. операция.

Привет @bhouston ,
Верно ли то же самое для матричных операций? Когда я думал о SIMD, я думал, что матричные операции 4 X 4 принесут наибольшую пользу. И, как мы все знаем, матрицы используются в каждом кадре анимации в Three.js на стороне JavaScript / ЦП, независимо от сложности приложения.

Если ребята из Babylon.js не возражают, вот подсказка, как все это начать:
https://github.com/BabylonJS/Babylon.js/blob/master/src/Math/babylon.math.js#L2030 -L2093

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

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

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

Полученный код также сложно отлаживать и поддерживать.

Одна из стратегий, которая может сработать, состоит в том, чтобы все векторы и матрицы использовали SIMD-совместимую компоновку памяти в качестве собственного представления - это то, во что Quake 3 верил в своей математической библиотеке. Но тогда вам нужно использовать 4 числа с плавающей запятой для типов vec2 и vec3 для эффективности, но тогда это становится проблематичным, когда вы хотите загрузить в графический процессор, потому что теперь у вас есть дополнительные поплавки.

Я понимаю, что вы имеете в виду, спасибо за понимание и опыт. Я полагаю, что некоторое время назад меня впечатлила презентация SIMD.js, вставить ее в three.js и поддерживать ее - это разные вещи. Было бы интересно, как вы сказали, провести некоторые сравнения производительности. Может быть, библиотеки физики, такие как Cannon.js и Oimo.js, которые используются вместе с three.js, получат больше преимуществ от SIMD?

@bhouston Ага, в этом есть смысл, хотя некоторые тесты были бы весьма интересны.

@erichlof, если вам интересно, я открыл ветку https://github.com/Globegitter/three.js/tree/include-SIMD , где я начал заменять Vector3 на SIMD. Это все еще тяжелая незавершенная работа, и мое время ограничено, так что посмотрим, как далеко я продвинусь. Кроме того, используя последнюю ночную версию Firefox, вы можете запускать этот код без полифилла (где нативная реализация, по-видимому, примерно в 20 раз быстрее по сравнению с полифилом: https://blog.mozilla.org/javascript/2015/03/10/state -of-simd-js-performance-in-firefox /).

@erichlof @jonnenauha Я чувствую себя обязанным указать, что классы es6 - это просто сахар, и они внутренне используют механизм прототипов для реализации всего во время выполнения.
Я довольно оптимистичен, что функции es6 не повлияют на производительность вычислений.

Возможно, вы немного поспешите заключить, что: действительно существуют разные пути кода для ES6 в каждом движке JS в (довольно сложной) реализации объектов JS.

Модули es6 могут повлиять на время загрузки, когда они, наконец, будут реализованы движками, потому что вы загружаете кучу маленьких файлов, а не один большой файл. HTTP / 2 может сделать это не проблемой.

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

Если компилятор Closure поймет, что Three.js позволит выполнить компиляцию в ES6 и увидеть, когда наступит подходящий момент для переключения, а также многие дополнительные преимущества. Я думаю, что именно к этому сейчас и следует приложить усилия ...

Но даже в этом случае умножение [SIMD] Matrix часто не является оптимальным, потому что вам нужно умножать столбцы на строки, что требует операции переупорядочения.

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

for i : 0..3:
    dst.col[i] = lhs.col[i] * rhs.co[i][0] // multiply vector by scalar
    for j : 1..3:
        dst.col[i] += lhs.col[i] * rhs_col[i][j] // multiply vector by scalar & add

Умножение матриц фактически просто применяет преобразование к векторам-столбцам правого операнда. Теперь преобразования можно рассматривать либо как набор точечных произведений (сбивающий с толку способ, который мы обычно используем с ручкой и бумагой), либо как линейную комбинацию векторов осей целевого пространства = вектор-столбцы левой стороны операнд.

@Globegitter Вау, это

@Globegitter Мне нравится, когда кто-то просто идет вперед и что-то делает, когда верят в это. Код устанавливает расходящиеся точки зрения быстрее, чем обсуждение.

где нативная реализация, по-видимому, в ~ 20 раз быстрее по сравнению с полифилом

Было бы интересно посмотреть, насколько медленнее polyfill по сравнению с non-SIMD

Я собираюсь установить Firefox Nightly, чтобы поэкспериментировать с новой веткой!

Также должна быть возможность попробовать его в Edge, включив экспериментальный и asm.js в about: flags

@Globegitter Я думаю, ваш редактор меняет пробелы, что приводит к действительно неприятным различиям: https://github.com/Globegitter/three.js/commit/d835ca3a22eed4ed4603534773ae55c29d5a8026

Я заметил, что вы делаете SIMD-тип как боковую машину:

https://github.com/Globegitter/three.js/commit/8ed9c1d351a3b0587a1f05051922d271d79f642d

Могу я предложить вам просто изменить Vector3 x, y, z на геттеры / сеттеры и сохранить только float32x4? Я думаю, что такой подход может быть намного проще реализовать с меньшими изменениями.

Я не уверен, как лучше всего определять свойства, но mrdoob делает что-то подобное здесь:

https://github.com/mrdoob/three.js/blob/5c7e0df9b100ba40cdcaaf530196290e16c34858/examples/js/wip/proxies/ProxyVector4.js#L18

Использование SIMD в качестве основного типа хранилища после математического типа, вероятно, является наиболее эффективным, никаких дополнительных преобразований не требуется. Вот математическая библиотека SSE Bullet Physics, если вам нужно руководство по любым стандартным векторным / матричным операциям:

https://code.google.com/p/bullet/source/browse/trunk/src/vectormath/sse/

@bhouston , спасибо за эти заметки. Я как бы сразу собирался посмотреть, как далеко я продвинусь за несколько часов, если раньше не много работал с тремя и SIMD (мы используем его в большинстве наших проектов). Так что эта обратная связь от кого-то, кто знает три, действительно ценится. И да, нужно отключить это в моем редакторе.

@tschw спасибо за замечание по математике матриц / векторов! Вы правы, что лучше.

@Globegitter Вот лучший пример установщика / получателя для прототипа объекта: https://github.com/mrdoob/three.js/blob/master/src/core/Object3D.js#L83

Несколько центов за работу над ES2015 (в основном в узле)

  • есть места, где движкам Javascript (например, V8) необходимо наверстать упущенное, оптимизируя функции ES6.
  • из моего опыта код вроде let x = 1, y = 2 деоптимизирует v8, хотя я ожидал, что v8 в конечном итоге поддержит его
  • перенесенный в ES5 код может выполняться медленнее, чем код ES6 (вот почему я предпочитаю использовать только поддерживаемые функции ES6 в> узле 4, то есть почти все, кроме системы импорта и экспорта)
  • Карты и наборы - это победа в производительности
  • Классы хорошие
  • Использование Babel может быть болезненным для вашего рабочего процесса, вероятно, не стоит усилий, если вы используете ES6 исключительно для синтаксического сахара.

Полгода назад я преобразовал некоторые функции Three.js (умножение матриц 4x4, Vector4 и т. Д.) В SIMD, и вы можете попробовать их. В какой-то момент он работал как букмарклет, но теперь может потребоваться обновление для работы с последней версией Three.

  • Firefox Nightly прямо из коробки поддерживает SIMD
  • Chrome с флагом --js-flags = "- harmony-simd" поддерживает JS-полифил SIMD, поэтому он будет медленнее, чем версия без SIMD. По крайней мере, вы можете проверить, работает ли это, и поэкспериментировать!

350% прирост производительности - ЛОЖЬ :)

Я также портировал часть Vector3, но она прокомментирована.

https://github.com/DVLP/three.turbo.js

Изменить: у меня где-то на жестком диске есть более свежая версия, поэтому я скоро обновлю этот проект

Потрясающе смотрел и смотрел +1 к этому.
Что было бы замечательно, так это система, которая проверяет производительность и включает или отключает такие функции в зависимости от указанной производительности.

Что было бы замечательно, так это система, которая проверяет производительность и включает или отключает такие функции в зависимости от указанной производительности.

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

Мы могли бы начать с выполнения SIMD-версии Matrix4 multiplyMatrices() поскольку в настоящее время это наиболее вызываемый метод в сложных сценах.

https://github.com/mrdoob/three.js/blob/dev/src/math/Matrix4.js#L383 -L419

screen shot 2016-08-30 at 20 46 29

@mrdoob загляни сюда, готово.
https://github.com/DVLP/three.turbo.js/blob/master/src/three.turbo.js

Попробуйте как букмарклет:
javascript:(function(){var script=document.createElement('script');script.src='//rawgit.com/DVLP/three.turbo.js/master/src/three.turbo.js';document.head.appendChild(script);})()

Ответственный фрагмент кода

THREE.Matrix4.prototype.multiplyMatrices = function(a, b) {
    var ae = a.elements,
      be = b.elements,
      tb = this.elements,
      arr1 = SIMD.Float32x4.load(ae, 0),
      arr3 = SIMD.Float32x4.load(ae, 4),
      arr5 = SIMD.Float32x4.load(ae, 8),
      arr7 = SIMD.Float32x4.load(ae, 12),
      arr2,
      arr4,
      arr6,
      arr8,
      res;
    // calculated version
        for (var i = 0; i < 4; i++) {
            arr2 = SIMD.Float32x4.splat(be[i * 4]);
            arr4 = SIMD.Float32x4.splat(be[i * 4 + 1]);
            arr6 = SIMD.Float32x4.splat(be[i * 4 + 2]);
            arr8 = SIMD.Float32x4.splat(be[i * 4 + 3]);
            res = SIMD.Float32x4.add(SIMD.Float32x4.add(SIMD.Float32x4.mul(arr1, arr2), SIMD.Float32x4.mul(arr3, arr4)), SIMD.Float32x4.add(SIMD.Float32x4.mul(arr5, arr6), SIMD.Float32x4.mul(arr7, arr8)));
            SIMD.Float32x4.store(tb, i * 4, res);
          }
}

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

В "инверсной" ветке больше функций
https://github.com/DVLP/three.turbo.js/blob/inverse/src/three.turbo.js

Какая разница в производительности?

https://jsfiddle.net/tk6zx5dm/6/

Это зависит. В Nightly, когда количество вычислений невелико (<1000), результат в 3 раза медленнее. Когда количество вычислений превышает 10000, скорость увеличивается на ~ 40%.

В Chrome с включенным флагом --js-flags="--harmony-simd" нет реального SIMD, но есть полифил JavaScript, поэтому очевидно, что скорость сейчас во много раз ниже.

Хорошим местом для тестирования будет проект Crosswalk (на основе Chromium). У них есть настоящая SIMD для Android, поэтому было бы интересно создать проект с кодом из этого JSFiddle, чтобы увидеть, каков будет результат.

Возможно, вы в любом случае не захотите включать полифил simd в свои примеры страниц. Просто людям немного удобнее их опробовать. Зарегистрируйте строку в консоли или поместите текст на экран, если нативный недоступен (полифил, вероятно, оставляет какие-то намеки на то, что он включен).

Я не могу себе представить, почему Chrome просто загружает полифилл js simd с --js-flags="--harmony-simd" , что просто не имеет смысла, когда это уже можно сделать на земле пользователя ?! Какая в этом польза. Может, начнут постепенно вставлять. Где вы читали, что на самом деле происходит с флагом, есть хорошие ссылки? Похоже, здесь находится «в разработке» https://www.chromestatus.com/features/5757910432874496

Изменить: к актуальной теме: я полагаю, что очень сложно поместить этот материал в three.js, если перфоманс находится повсюду, от нескольких объектов до множества объектов. Если все реализации могут улучшить производительность от 1 до N объектов, эту функцию следует обнаружить и использовать там, где это имеет смысл. Если нативные имплементы несовместимы, я не вижу, чтобы все это куда-то пошло, так зачем вообще над этим работать, тратить часы разработки на что-то более продуктивное.

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

не могу представить, почему Chrome просто загружает полифилл js simd с --js-flags = "- harmony-simd"

Я думаю, что это довольно распространенная практика, когда браузеры делают это таким образом, чтобы пользователи могли начать что-то тестировать. Например, если я правильно понимаю, именно так WASM будет изначально введен в браузеры.

Все аргументы, подтверждающие неизбежность необходимости центуриона. Мониторинг производительности в реальном времени, который может включать или отключать функции и определять оптимальную производительность. Так что даже плотность карты теней должна изменяться в зависимости от расстояния до камеры и т. Д. В любом случае, я знаю, что консенсус решил, что это будет сторонний инструмент и не нужен. Тем не менее, я просто хочу сохранить эту точку в сознательном, если не подсознательном уме.
Возможно, вы просто проверяете наличие поллифила и отключаете SIMD, но снова FPS говорит обо всем. Приоритеты включения или отключения, вероятно, лучше всего зависят от предпочтений пользователя / приложения. Спасибо за внимание! Я с нетерпением жду более быстрого GL в ближайшем будущем. Будем готовы затмить остальное.

Похоже, что процесс загрузки данных в SIMD может создавать накладные расходы, которые бросают вызов преимуществам использования SIMD в Nightly. Мне очень интересно узнать о производительности в Chrome, но последняя версия Chromium с реальной SIMD находится здесь http://peterjensen.github.io/idf2014-simd/
Это старый.

Обновлять:
теперь SIMD работает и в Edge. Вы можете включить его, перейдя в about: flags и отметив «Включить экспериментальные функции JavaScript» (перезапустить Edge)
Не уверен, правда ли это SIMD или полифил. Этот тест показывает на моей машине примерно на 40% медленнее SIMD: / https://jsfiddle.net/tk6zx5dm/6/

вариант теста с объектами SIMD, кэшированными в объекте Matrix4, не уверен, что это когда-нибудь будет полезно
https://jsfiddle.net/tk6zx5dm/15/
Интересно то, что код с кешированными объектами SIMD _ иногда_ быстрее даже в Chrome, который использует polyfill SIMD (...? Странно)

THREE.Matrix4.prototype.multiplyMatrices = function(a, b) {
  var i = 4;
  while(i--) {
    SIMD.Float32x4.store(this.elements, i * 4, 
      SIMD.Float32x4.add(
        SIMD.Float32x4.add(
          SIMD.Float32x4.mul(
            a.cacheSIMDRow1,
            b.cacheSIMDSplat[i * 4]
          ),
          SIMD.Float32x4.mul(
            a.cacheSIMDRow2,
            b.cacheSIMDSplat[i * 4 + 1]
          )
        ),
        SIMD.Float32x4.add(
          SIMD.Float32x4.mul(
            a.cacheSIMDRow3,
            b.cacheSIMDSplat[i * 4 + 2]
          ), 
          SIMD.Float32x4.mul(
            a.cacheSIMDRow4,
            b.cacheSIMDSplat[i * 4 + 3]
          )
        )
      )
    );
  }
}

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

THREE.Matrix4.prototype.updateSIMDCache = function() {
  this.cacheSIMDRow1 = SIMD.Float32x4.load(this.elements, 0);
  this.cacheSIMDRow2 = SIMD.Float32x4.load(this.elements, 4);
  this.cacheSIMDRow3 = SIMD.Float32x4.load(this.elements, 8);
  this.cacheSIMDRow4 = SIMD.Float32x4.load(this.elements, 12);

  if(!this.cacheSIMDSplat) {
    this.cacheSIMDSplat = [];
  }
  for(var i = 0; i < 16; i++) {
    this.cacheSIMDSplat.push(SIMD.Float32x4.splat(this.elements[i]));
  }
};

Мне любопытно, был ли пересмотрен стиль ES6? Прямо сейчас весь код непригоден для использования вживую без запуска конкатенатора, так почему бы также не запустить babel и не начать использовать ES6 там, где это необходимо?

Прямо сейчас весь код непригоден для использования вживую без запуска конкатенатора, так почему бы также не запустить babel и не начать использовать ES6 там, где это необходимо?

В основном из-за отсутствия тестов на влияние кода, созданного babel, на производительность. Кроме того, я слышал, что V8 производит более быстрый код при использовании var вместо let / const.

К вашему сведению: недавно я начал пробовать bublé, который «ограничивается функциями ES, которые могут быть скомпилированы в компактный, производительный ES5».

Нижняя часть этой ссылки помогает объяснить циклы var vs let in
http://stackoverflow.com/questions/21467642/is-there-a-performance-difference-between-let-and-var
Лично я жду, когда решения none transpiler попадут в браузер. например, для 'await', чем раньше, тем лучше, но сейчас, может быть, это должно быть написано таким образом и пропущено (ужасно изуродовано) транспилером, но если он работает в Chrome ?! так что тестирование для других браузеров? Я говорю: «Пусть едят торт ... или используйте Chrome». (мое любимое выражение).
Я думаю, что 'let' следует использовать в ситуации, когда предпочтительнее проверять с помощью тестов, что это лучше сделать.
Я полагаю, это похоже на то, что 'var' поднимается, чтобы избежать области видимости, но вы можете захотеть этого, и тогда 'let' будет лучше. Я думаю / надеюсь, что 'let' также должно уменьшить объем вашей памяти в определенных ситуациях.

Транслируемый код никогда не будет таким быстрым, как оптимизация вручную. Жаль, что JSPerf не работает. Я бывал в нем чаще, чем в Google.
Изменить: JSPerf.com не работает! Я просто предположил, что он мертв навсегда после того, как он не работал в течение года
let 3 раза медленнее, чем var в моем Chrome Canary: https://jsperf.com/let-vs-var-performance/14
в Firefox и Edge нет разницы в скорости, но Chrome наиболее важен.
Может кто-нибудь протестировать в Safari?

Классы кажутся классными и современными! кто-нибудь знает, есть ли это уже в расписании?

@ Rubinhuang9239 Я не видел, чтобы кто-нибудь попробовал.

пусть в 3 раза медленнее, чем var в моем Chrome Canary: https://jsperf.com/let-vs-var-performance/14

Что бы это ни стоило, let и const теперь немного быстрее, чем var для меня в Chrome 66, Firefox 59 и Edge 42, используя этот тест.

Я думаю, переключение классов должно быть очень простым - основная работа заключалась в принятии объединения, которое было сделано некоторое время назад. Не удивлюсь, если герой сможет реализовать классы в ThreeJS за пару часов.

Классов много, так что, возможно, это займет около 8 часов, если вы делали это вручную.

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

@looeee прошло уже больше года, поэтому неудивительно, что ES6 удалось догнать производительность

2019 год - это год, когда, наконец, начнется внедрение некоторого кода ES6 в примерах / документах, верно, @mrdoob? 😄

ES6 уже довольно давно является стандартом, новые разработчики изучают ES6. Также мы можем прекратить поддержку IE11 в примерах, как вы, ребята, обсуждали в # 16220, какие разработчики рассматривают примеры three.js, использующие IE11? 😅

Я думаю, что наиболее необходимые функции для упрощения кода для новичков - это классы и строки шаблонов, не забывая при этом о const / let по умолчанию.

Я могу внести свой вклад, если мы решим начать.

Шаг за шагом. Давайте начнем с обновления примеров, чтобы сейчас использовать three.module.js .

Шаг за шагом. Давайте начнем с обновления примеров, чтобы сейчас использовать three.module.js.

Этот шаг уже давно выполнен. Может пора официально перейти к следующему шагу?

Два кандидата:

  1. const / let
  2. классы

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

По теме: # 11552, # 18863

Если я правильно понимаю, проблема в том, что мы не можем ничего преобразовать в классы ES6, если они расширены примерами, пока примеры тоже не будут преобразованы. И это может означать ожидание, пока examples/js не исчезнет? Если мы не сможем подтвердить, что сценарий modularize будет поддерживать классы, для преобразования файлов examples/js одновременно с их родительскими классами.

Насколько я понимаю, examples/js - это своего рода все лишние функции, которые, тем не менее, крутые, но которые, если мы все объединимся в основной src/... чрезмерно раздутят его. По сути, это ответ на вопрос «Предоставляем ли мы примеры / сценарии обычно создаваемых x, y, z?». Я рискну предположить, что ответ three.js в основном положительный, но в качестве обучающего материала на веб-сайте. Удаление examples/js в этот момент не может быть и речи. Хотя, возможно, я неправильно понял, как ссылаются / используются examples/js 🤔 дайте мне знать.

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

Я отвлекся.

пока примеры тоже не будут преобразованы.

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

@ Определенно Может быть, мы не удаляем функциональность в examples/js , стоит отметить два каталога:

  • examples/js/*
  • examples/jsm/*

Первый содержит устаревшие файлы, второй - модули ES, созданные из этих файлов, с той же функциональностью. В конечном итоге мы удалим первую. Скрипт, выполняющий преобразование, в настоящее время не поддерживает классы ES. Поэтому, пока он не будет удален, файлы в examples/js не могут быть преобразованы в классы ES. Некоторые из них расширяют файлы в src/ , и вы не можете расширять классы ES без использования классов ES, так что это блокирующая зависимость.

ах, смутил предыдущий комментарий

И это может означать ожидание, пока не исчезнут примеры / js?

теперь имеет смысл.

modularize.js напоминает мне мой первоначальный проект, который привел меня сюда. Конвертер . Я видел здесь комментарии о переходе на классы ES6, поэтому я подумал, что вместо этого просто перейду сюда.

Итак, если examples/js каким-то образом расширяет src , оба должны быть преобразованы в классы ES6 одновременно
или...
работать над модулем, пока он не сгенерирует классы / es6?

мы не можем ничего преобразовать в классы ES6, если это расширено примерами

В ядре все еще есть много вещей, которые не расширены в примерах, почему бы нам не начать с этого?

Для меня это звучит нормально.

@ Mugen87, что-то еще блокировало изменение класса ES, или что-то еще?

В ядре все еще есть много вещей, которые не расширены в примерах, почему бы нам не начать с этого?

Список скриптов, не расширенный примерами .

редактировать: список обновлен!

Блокираторы - это такие разделы:

https://github.com/mrdoob/three.js/blob/6865b8e6367d0ce07acbacfae6663c4cce3ac21e/examples/js/loaders/ColladaLoader.js#L6 -L12

https://github.com/mrdoob/three.js/blob/6865b8e6367d0ce07acbacfae6663c4cce3ac21e/examples/js/cameras/CinematicCamera.js#L38 -L39

https://github.com/mrdoob/three.js/blob/6865b8e6367d0ce07acbacfae6663c4cce3ac21e/examples/js/controls/OrbitControls.js#L1149 -L1150

Наиболее вероятными шаблонами будет использование THREE.<class>.call и Object.create( THREE.<class> . Это означало бы, что Loader, EventDispatcher и PerspectiveCamera (среди, вероятно, многих других) еще не могут быть преобразованы в классы.

https://github.com/mrdoob/three.js/commit/1017a5432eede4487436d6d34807fda24b506088

Хорошо, я думаю, мы можем начать с let и const в src/ .

@DefinitoMaybe. Вы хотели бы помочь с этим?

🎉 черт возьми!

Я просто хотел выразить обеспокоенность тем, что если вы загружаете горячий код, мои опасения, что const, вызовут проблемы. Если во всем JavaScript верно, что объекты полностью перезаписывают const, тогда нет проблем. Увы, если они этого не сделают, никогда не следует использовать все const. Я просто объединяю объектные структуры с функциями кода, назначенными клавишам этих объектных деревьев (например, структур), поэтому я избегаю использования let или const по большей части.
В любом случае, это то, о чем стоит подумать, и я в основном считаю, что const никогда не следует использовать и это действительно бесполезно. В основном из-за моих проблем с загрузкой хоткода.
Тем не менее, я думаю, что они не так постоянны, как вы думаете, поэтому, возможно, кто-то, кто понимает, что больше, может объяснить, что это бессмысленная проблема с перезагрузкой импорта или чем-то еще. Спасибо за внимание и вклад.
Да будет «пусть»! Наконец-то.

Крокфорд сказал, что var было большой ошибкой, но его нельзя было изменить, поэтому 'let' был создан, но var считается некорректным, и код 'let' должен был быть исправлением для var, но он сломал бы несколько плохо закодированных крайних случаев. скрываясь в дикой природе. Строгий режим и подъем - это проблемы, связанные с этой темой.

@MasterJames нет абсолютно никаких проблем с горячей перезагрузкой при использовании const.

Я работаю в среде React, и горячая перезагрузка там является нормой, как и const и let, которые в настоящее время являются стандартом.

Согласен, горячей перезагрузке это не помешает. Возможно, вы ошибочно приняли const за неизменность объектов с помощью Object.freeze ? Мы не планируем этого делать.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги