итерация всех Rectangles

  • Автор темы Автор темы ssyabr
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.

ssyabr

Участник
Топикстартер
Сообщения
48
Реакции
0
Всем привет!

Необходимо обойти все Rectangles документа максимально быстро. В голову приходит проверка pageItem.constructor.name на "Rectangle", при обходе allPageItems документа:

PHP:
for(var j = 0, length = doc.allPageItems.length; j < length; ++j)
{
  var pageItem = doc.allPageItems[j];
  if(pageItem.constructor.name == "Rectangle")
  {
    //...
  }
}

проверка имени констркуктора на соответствие "Rectangle" работает непозволительно долго...

В идеале было бы наличие allRectangles у документа или на худой конец хотя бы числовой идентификатора класса объекта(все же было бы быстрее сравнивать число а не строку)



Спасибо!

ЗЫ
2 Strizh: название форума видишь? естественно только посредством скриптов ;-)
 
Ответ: итерация всех Rectangles

Doc.Rectangles

А в Дельфях все итерации, класс-не класс, мухой работают...
 
Ответ: итерация всех Rectangles

2 cherry-m,

Doc.Rectangles это же совсем не то! Мне нужны именно ВСЕ Rectangles, а не top items!

по поводу дельфина : скорость вызова метода зависит от возможности использования раннего связывания клиентом, кое Delphi поддерживает. При обработке же скрипта используется так называемое позднее связывание, реализуемое посредством IDispatch. Это все понятно! Но! Мне необходимо реализовать максимально быстро для так называемых "глупых клиентов".
 
Ответ: итерация всех Rectangles

"а не top items" - тут я немного "плаваю"... Это термин из документации? В смысле, и те прямоугольники, которые являются частью группы, заключены во фреймы и пр.? Тады - ой, без проверки имени класса не обойтись, пожалуй, самое все ж грамотное и красивое решение. Есть еще мнения?
 
Ответ: итерация всех Rectangles

В смысле да, и те прямоугольники, которые являются частью группы и inlines тоже...
 
Ответ: итерация всех Rectangles

ssyabr сказал(а):
Doc.Rectangles это же совсем не то!

Лень проверять, но только что писал для Илла

myDoc.TextFrames - это ВСЕ текстовые фреймы, даже входящие в группы. Подозреваю что в ИД аналогично.
 
Ответ: итерация всех Rectangles

ragman сказал(а):
Лень проверять, но только что писал для Илла

myDoc.TextFrames - это ВСЕ текстовые фреймы, даже входящие в группы. Подозреваю что в ИД аналогично.

Я проверял, в myDoc.rectangles не входят элементы из групп и инлайны...
 
Ответ: итерация всех Rectangles

100%
myDoc.TextFrames - текстовые фреймы только свободно лежащие, вчера ковырялся с этим. AllPageItems - и вперед
 
Ответ: итерация всех Rectangles

Дико извиняюсь - лень подвела.
Проверил - был неправ.
 
Вопрос закрыт. Всем спасибо!

Проблема была в другом : вынес получение allPageItems из цикла, скорость выросла на порядки.

PHP:
var allPageItems = doc.allPageItems;
for(var j = 0, length = allPageItems.length; j < length; ++j) 
{ 
  var pageItem = allPageItems[j]; 
  if(pageItem.constructor.name == "Rectangle") 
  { 
    //... 
  } 
}
 
Ответ: Вопрос закрыт. Всем спасибо!

Более того, если все ректанглы собрать сперва в один массив, а потом их обрабатывать, будет еще быстрее.
 
Ответ: Вопрос закрыт. Всем спасибо!

Хм....
Судя по приведенной программе, прямоугольники в группах и InLine опять таки не попадают в обработку...
Или я не прав?
 
Ответ: Вопрос закрыт. Всем спасибо!

Oleg Butrin сказал(а):
Более того, если все ректанглы собрать сперва в один массив, а потом их обрабатывать, будет еще быстрее.

Это почему? Должно быть наоборот дольше! Вот лишние шаги:
-создание коллекции
-ее наполнение
-иттерирование по элементам
 
Ответ: Вопрос закрыт. Всем спасибо!

ssyabr сказал(а):
Проблема была в другом : вынес получение allPageItems из цикла, скорость выросла на порядки.

А тогда можно еще вытащить из цикла получение количества элементов:

var allPageItems = doc.allPageItems;
ItemsCount = allpageItems.length;

for(var j = 0; j < ItemsCount; ++j)
{
...
}
 
Ответ: Вопрос закрыт. Всем спасибо!

ssyabr сказал(а):
Это почему? Должно быть наоборот дольше! Вот лишние шаги:
-создание коллекции
-ее наполнение
-иттерирование по элементам
Создание массива занимает время, экспоненциально приближающееся к нулю. Равно и наполнение. Потому, что никакого оперирования элементами не происходит.

Вот пример:

PHP:
with (app) {
	var myArray = new Array;
	var mySD1 = new Date;
		var myStory = selection[0].parentStory;
	for (var counter = 0; counter < myStory.characters.length; counter++) {
		if (myStory.characters[counter].contents == "A") {
			myArray.push(myStory.characters[counter]);
		}
	}
	for (el in myArray) {
		el.contents = "A";
	}
	var myED1 = new Date;
	var Et1 = Number(myED1 - mySD1);	
	
	var mySD2 = new Date;
	var myStory = selection[0].parentStory;
	for (var counter = 0; counter < myStory.characters.length; counter++) {
		if (myStory.characters[counter].contents == "A") {
			myStory.characters[counter].contents = "A";
		}
	}
	var myED2 = new Date;
	var Et2 = Number(myED2 - mySD2);
	
	alert("With use array: " + Et1 + ". No use array: " + Et2);
}

Создаем документ, делаем Story тысяч на десять знаков английского Placeholder. Выделяем один из фреймов и запускаем скрипт.
Разница в десятые секунды в ту или иную пользу (у меня чаще в пользу варианта с массивом).

Главный тормоз обычно в скриптах обусловлен привычкой именования объектов при переборе. Это оправдано, когда скрипт предназначен для чтения и дальнейшего редактирования, поскольку длинные цепочки вида activeDocument.allPageObject.images[j].paths[l].pathPoint[m] для восприятия полная абракадабра. Если же скрипт прост и должен быть очень быстр, то именование переменных следует оставить в прошлой грешной жизни - только цепочкой.

Как пример можно использовать следующий скрипт на том же документе:

PHP:
with (app) {

	var mySD1 = new Date;
	var myStory = selection[0].parentStory;
	for (var counter = 0; counter < myStory.characters.length; counter++) {
		var myEl = myStory.characters[counter];
		if (myEl.contents == "A") {
			myEl.contents = "A";
		}
	}
	var myED1 = new Date;
	var Et1 = Number(myED1 - mySD1);
		
	var mySD2 = new Date;
	var myStory = selection[0].parentStory;
	for (var counter = 0; counter < myStory.characters.length; counter++) {
		if (myStory.characters[counter].contents == "A") {
			myStory.characters[counter].contents = "A";
		}
	}
	var myED2 = new Date;
	var Et2 = Number(myED2 - mySD2);
	
	alert("With use named var: " + Et1 + ". No use var: " + Et2);
}

Обратите внимание на разрыв в скоростях. И сообщите тут результаты.
 
Ответ: Вопрос закрыт. Всем спасибо!

cherry-m сказал(а):
А тогда можно еще вытащить из цикла получение количества элементов:

Это и так сделано, будьте внимательны!
PHP:
for(var j = 0, length = allPageItems.length; j < length; ++j)
 
Ответ: Вопрос закрыт. Всем спасибо!

ssyabr сказал(а):
Это и так сделано, будьте внимательны!

Будет исполнено, ваше высокоблагородие! Синтаксис слабознакомый...
 
Ответ: Вопрос закрыт. Всем спасибо!

Oleg Butrin сказал(а):
Создание массива занимает время, экспоненциально приближающееся к нулю. Равно и наполнение. Потому, что никакого оперирования элементами не происходит.

Давайте подумаем, а что меряет Ваш первый скрипт? Показывает ли он разницу во времени между выполнением при помощи

дополнительного массива и без него? Ответ прост - нет.
Что же меряет Ваш cкрипт? Ваш скрипт меряет все что угодно : получение свойств, выполнение методов, чтение содержимого text

story, изменение ее же содержимого. Но Ваш скрипт не меряет самого главного, а именно создание массива и наполнение массива!
Давайте не будем хитрить, и рассмотрим следующий видоизмененный пример:

PHP:
with (app) 
{ 
	var i1 = 0, i2 = 0;

	var myArray = new Array; 
	
	var mySD1 = new Date; 
	var myStory = selection[0].parentStory; 
	var characters = myStory.characters;
	for (var counter = 0, length = characters.length; counter < length; ++counter) 
	{ 
		var character = characters[counter];
		myArray.push(character); 
	} 
	for (el in myArray) 
	{ 
		++i1;
	} 
	var myED1 = new Date; 
	var Et1 = Number(myED1 - mySD1); 



	var mySD2 = new Date; 
	var myStory = selection[0].parentStory; 
	var characters = myStory.characters;
	for (var counter = 0, length = characters.length; counter < length; ++counter) 
	{ 
		var character = characters[counter];
		++i2;
	} 

	var myED2 = new Date; 
	var Et2 = Number(myED2 - mySD2); 

	alert("With use array: " + Et1 + ". No use array: " + Et2); 
}

В нем я попытался убрать все лишнее. Результат на лицо : второй кусок кода отработал в 1,5 раза быстрее.

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

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

чего? От колбасок? Видимо от количества элементов. Так? Это в свою очередь делает справедливым утверждение : "создание массива занимает время, экспоненциально приближающееся к бесконечности, при увеличении количества элементов".

Давайте подумаем, как могут быть реализованы массивы? Очевидно предположить два варианта:
- вариации связанных списков
- используя непрерывный блок памяти.

При первом варианте приходится платить за overhead при иттерировании, и получении элемента по индексу, операции не характерной для списков. В тоже время вставка происходит очень быстро. Вариант с непрерывным блоком памяти всем хорош, но время потраченное на перераспределение элементов может быть критическим. Очевидно, что надо выбирать между дешевой вставкой элемента в коллекцию и временем потраченным на произвольный доступ к элементу. Ну что же... За все надо платить... Бесплатно только, сами знаете что может быть
 
Ответ: Вопрос закрыт. Всем спасибо!

Oleg Butrin сказал(а):
Главный тормоз обычно в скриптах обусловлен привычкой именования объектов при переборе. Это оправдано, когда скрипт предназначен для чтения и дальнейшего редактирования, поскольку длинные цепочки вида activeDocument.allPageObject.images[j].paths[l].pathPoint[m] для восприятия полная абракадабра. Если же скрипт прост и должен быть очень быстр, то именование переменных следует оставить в прошлой грешной жизни - только цепочкой.
//...
Обратите внимание на разрыв в скоростях. И сообщите тут результаты.


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

PHP:
var mySD1 = new Date;
var myStory = selection[0].parentStory;
var characters = myStory.characters;
var myEl;
for (var counter = 0, length = characters.length; counter < length; ++counter) 
{
	myEl = characters[counter];
	if (myEl.contents == "A") 
	{
		myEl.contents = "A";
	}
}

Я в интерпретируемых языках не особенно уверенно себя чувствую, но для транслируемых языков, в частности C, должно быть быстрее 2-х предложенных.

Спасибо!
 
Статус
Закрыто для дальнейших ответов.