Доступны ли какие-либо проходы оптимизации в Fable? - PullRequest
2 голосов
/ 10 января 2020

Я написал следующий код в Fable REPL :

open Fable.Core

let inline sqr x = x * x

// Filters out `points` that are more than `radius` away
let inRadius radius points = 
  points
  |> List.filter (fun (x, y) -> sqr x + sqr y <= sqr radius)

И вывод JavaScript был:

import { filter } from "fable-library/List.js";

export function inRadius(radius, xs) {
  return filter(function predicate(tupledArg) {
    return tupledArg[0] * tupledArg[0] + tupledArg[1] * tupledArg[1] <= radius * radius;
  }, xs);
}

Более оптимальный JavaScript будет:

import { filter } from "fable-library/List.js";

export function inRadius(radius, xs) {
  const radiusSquared = radius * radius; 

  return filter(function predicate(tupledArg) {
    return tupledArg[0] * tupledArg[0] + tupledArg[1] * tupledArg[1] <= radiusSquared;
  }, xs);
}

(Это только один пример оптимизации, которая может быть применена, есть еще много возможностей)

В JavaScript это Трудно безопасно выполнить эту оптимизацию из-за отсутствия типов. Однако в исходном коде F # мы знаем тип radius, поэтому мы можем безопасно выполнить эту оптимизацию. Мне кажется, это большое преимущество Fable перед JavaScript.

Однако такую ​​оптимизацию нужно где-то реализовать.

  • Можно ли включить подобные оптимизации в Fable?
  • Если нет, существуют ли другие инструменты, которые могут выполнять такие оптимизации?

1 Ответ

6 голосов
/ 10 января 2020

Я бы ожидал, что от Fable или любого другого транспилятора сохранится структура кода. Таким образом, вы можете оптимизировать код F # для вычисления радиуса ^ 2 только один раз.

open Fable.Core

let inline sqr x = x * x

// Filters out `points` that are more than `radius` away
let inRadius radius =
    let radiusSqr = sqr radius
    List.filter (fun (x, y) -> sqr x + sqr y <= radiusSqr)
...