Как вы представляете класс C ++ в V8 Javascript Engine, чтобы он мог быть создан с использованием нового?

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

  • Вне конвейера используйте:
    $objects.Name
    (PSv3 +), как показано в ответе rageandqq , который синтаксически проще и намного быстрее. Доступ к свойству на уровне коллекции для получения значений членов в качестве массива называется перечислением членов и является функция PSv3 + ; Компромиссы: как входной массив сбора, так и выходной массив должны вписываться в память в целом . Если входная коллекция сама является результатом команды (конвейера) (например, (Get-ChildItem).Name), эта команда должна сначала выполняться до завершения до того, как будут доступны элементы результирующего массива.
  • В конвейере , где результат должен быть обработан дальше или результаты не помещаются в память в целом, используйте:
    $objects | Select-Object -ExpandProperty Name
    . Необходимость в -ExpandProperty объясняется в ответ Скотта Саада . Вы получаете обычные преимущества конвейера от обработки по одному, что, как правило, дает выход сразу и сохраняет постоянство памяти (если вы в конечном итоге не собираете результаты в памяти). Компромисс: использование трубопровода сравнительно медленное .

Для коллекций ввода small (массивы) вы, вероятно, не заметите разницы и, особенно в командной строке, иногда можете ввести команду легко становится более важным.


Вот простая альтернатива, которая, однако, является самым медленным ; он использует упрощенный синтаксис , называемый оператором (опять же, PSv3 +):; например, следующее решение PSv3 + легко добавляется к существующей команде:

$objects | % Name      # short for: $objects | ForEach-Object -Process { $_.Name }

Для полноты: малоизвестный оператор коллекции PSv4 + .ForEach() - еще одна альтернатива:

# By property name (string):
$objects.ForEach('Name')

# By script block (much slower):
$objects.ForEach({ $_.Name })
  • Этот подход похож на перечисление участника (те же компромиссы), за исключением более медленного (хотя все же заметно быстрее, чем конвейер).
  • Для извлечения единственного значения свойства значением name ( string ) это решение находится на одном уровне с перечислением членов (хотя последнее синтаксически проще).
  • Вариант script-block , хотя и намного медленнее, допускает произвольные преобразования ; это более быстрый вариант «все-в-памяти-в-одном», альтернативный командному коду ForEach-Object .

Сравнение производительности различных подходов

Ниже приведены временные интервалы выборки для различных подходов на основе входного набора объектов 100,000; абсолютные цифры не важны и варьируются в зависимости от многих факторов, но это должно дать вам представление о относительном :

Approach                                          Seconds
--------                                          -------
 $objects.ForEach('Number')                       0.060
 $objects.Number                                  0.065
 $objects | Select-Object -ExpandProperty Number  0.859
 $objects.ForEach({ $_.Number })                  1.008
 $objects | % Number                              4.380
  • Самый быстрый на основе трубопровода решение более чем в 10 раз медленнее, чем решения для коллекции-оператора на основе перечисления / свойства-имени.
  • Использование для блока сценария на каждой итерации резко замедляет работу, так что самое быстрое решение на основе трубопроводов (Select-Object -Expand) превосходит коллекцию-operat [-g39] [-40] % Number на основе сценария
  • % Number, которая является наихудшим из обоих миров: конвейер, который использует блок сценария на каждой итерации (как указано, % Number является эквивалентом % { $_.Number }).

Примечание. Интересно, что с тем же тестом в PowerShell Core v6.0.2 на macOS дает другое ранжирование (хотя основное наблюдение за тем, что все еще более медленные конвейеры все еще применяются): перечисление членов происходит быстрее, и даже решение на основе сценария .ForEach() заметно быстрее, чем Select-Object -ExpandProperty.


Исходный код f или тестов:

# Number of input objects to create.
$count = 1e5 # 100,000

# Create sample input objects.
$objects = 1..$count | % { [pscustomobject] @{ Number = $_ } }

# An array of script blocks with the various approaches.
$approaches = { $objects | Select-Object -ExpandProperty Number },
              { $objects | % Number },
              { $objects.ForEach('Number') },
              { $objects.ForEach({ $_.Number }) },
              { $objects.Number }

# Time the approaches and sort them by execution time (fastest first):
$approaches | % {
    $scriptBlock = $_
    Measure-Command $scriptBlock |
      Select-Object @{ n='Approach'; e = { $scriptBlock.ToString() } } , Ticks
} | 
    Sort-Object Ticks | 
      Format-Table Approach, @{ n = 'Seconds'; e = { '{0:N3}' -f ($_.Ticks / 1e7) } }

30
задан Steve Hanov 18 June 2010 в 02:33
поделиться

1 ответ

Я не знаю, как точно этого добиться в движке V8 Js, но, как и в мире Python, вы можете просто сделать следующее. ваш класс Image:

class Image
{
public:
    Image(int w, int h);
    int Width(void) const;
};

напишите несколько функций-оберток и предоставьте эти функции миру Js:

Image* Image_New(int w, int h) { return new Image(w, h); }
void Image_Delete(Image* pImage) { delete pImage; }
int Image_Width(const Image* pImage) { return pImage->Width(); }

добавьте следующие коды в ваш файл js:

var Image = function (w, h) {
    this.image = new Image(w, h);
    this.Width = function() {
        return Image_Width(this.image);
    };
};

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

-11
ответ дан 28 November 2019 в 00:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: