24 июня 2012 г.

У кого длиннее метод

Во Flex'е многие методы имеют длинный список параметров.
Вот к примеру сигнатура:
EventDispatcher.addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void

В силу того, что параметры метода неименованные, читать код вызова не очень комфортно.

В Objective C этот вопрос решен именованными параметрами.

В коде же Flex фреймворка создатели решили это использованием вот таких комментариев: systemManager.getSandboxRoot().addEventListener (MouseEvent.MOUSE_UP, systemManager_mouseUpHandler, true /* useCapture */); 

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

Без некоторых комментариев в коде Flex фреймворка просто не разобраться, и это проблема не Flex или кода, это во многом проблема асинхронности, событийной модели.

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

Однако, как платформа, как то, что она предоставляет конечным пользователям Adobe Flash и Flex это несомненно великое!

8 июня 2012 г.

V8 и Javascript: оптимизация циклов в Chrome

Конечно, следует внимательнее посмотреть презентацию Егорова One day life in V8 (http://2012.jsconf.us/), но меня позабавило следующее при реализации функции, подсчитывающей количество делителей натурального числа.

Весь код на PasteBin


Вариант 1: работает за 1317 мс на 1E8
function divisors_count ( n ) {// 1E8 -> 1317ms
  if (n == 1) return 1;
  i = 1;
  count = 0;
  p = 0;
  n2 = n/2;
  while (i < n2 + 1 && p != i) {
    d = n / i;
    if (d % 1.0 == 0) {
      count+=2;
      p = d;
    }
    i++;
  }
  return count;
}

Вариант 2: работает быстрее, за 1246 мс
function divisors_count ( n ) {// 1E8 -> 1246ms
  if (n == 1) return 1;
  i = 1;
  count = 0;
  p = 0;
  while (i < n / 2 + 1 && p != i) {
    d = n / i;
    if (d % 1.0 == 0) {
      count+=2;
      p = d;
    }
    i++;
  }
  return count;
}

То есть получается что вариант, в котором вынесено за пределы цикла выражении n / 2 работает МЕДЛЕННЕЕ!
Между тем, более оптимальным алгоритмом подсчета количества делителей на Javascript является следующий:
function divisors_count (n) { // 1E8 -> 580ms
  if (n == 1) return 1;
  i = 1;
  count = 0;
  p = 0;
  while (i < n / 2 + 1 && p != i) {
    d = n % i;
    if (d == 0) {
      count+=2;
      p = n/i;
    }
    i++;
  }
  return count;
}

Что достаточно очевидно — в цикле мы выполняем деление только один раз. И один раз делаем когда добавляем в счет. т.к. делителей намного меньше чем число итераций, то следовательно второе деление менее трудозатратно.