On-line: PSP, гостей 0. Всего: 1 [подробнее..]
АвторСообщение
администратор




Пост N: 2792
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 18.03.13 17:35. Заголовок: Ascan ?


 
Есть массив вида {{},{},{}}

поиск веду в первом элементе
do while !eof()
..
if ascan(klnmas[1],{|fff| fff==nakl_r1->kod_kl})==0
skip
loop
endif
.......
skip
enddo
медленновато что то или меня уже плющит....
есть какой то другой аналог Ascan который пошустрее работает ?
Понятно что вот так быстрее будет
if ascan(klnmas[1],nakl_r1->kod_k)==0
skip
loop
endif


RDD скипает быстрее чем работает Ascan с блоком кода....


Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 44 , стр: 1 2 3 All [только новые]


постоянный участник




Пост N: 170
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 20.03.13 14:23. Заголовок: Pasha пишет:Конечно,..


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


В bcc использовал вашу функцию AADDU(<aArray>, <xKey>, <nSum1>, [nSum2], ...) при переходе на msvc она не перенеслась, стал использовать Hash (class bkHash, sum method. см. выше), протестировал по скорости в bcc оба способа. Ваш на десятые доли секунды быстрее (тестировал одной на годовой базе). Поэтому очень спокойно перешел на Hash.


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2817
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 16:17. Заголовок: Dima пишет: hb_hEva..


Dima пишет:

 цитата:
hb_hEval( hmas, {|key,sval,ind| if(sval[1]==3,aadd(fmas,key),)})
// при размере массива 700000 записей hb_hEval работает 530 мс , хочется что то побыстрее



 
dbeval( {|| hmas[recno()]:={kod_kl,nomer}})

? len(hmas) // 700000 ключей

fmas:={}
nsec:=seconds()
hb_hEval( hmas, {|key,sval,ind| if(sval[1]==5,aadd(fmas,key),)})
? (seconds()-nsec)*1000 // 594 mc


fmas:={}
nsec:=seconds()
for each v in hmas
if v:__enumValue()[1]==5
aadd(fmas,v:__enumKey())
endif
next
? (seconds()-nsec)*1000 // 437 mc тут побыстрее будет



А еще быстрее можно сделать выборку ? ;)

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2771
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 20.03.13 19:16. Заголовок: Dima пишет: А еще б..


Dima пишет:

 цитата:
А еще быстрее можно сделать выборку ? ;)



Можно перевернуть хеш. То есть, в качестве ключа использовать kmkod, а вместо значения - массив {{recno(), kod_kl, codn}, ...}
Если нужны только номера записей, можно добавлять только recno()

примерно так:

hmas:={=>}

// разверну для ясности dbeval
go top
while ! eof()
hmas[kmcod] := {}
AADD(hmas[kmcod], {recno(), kod_kl, codn})
// или
AADD(hmas[kmcod], recno())
skip
enddo

Тогда значением hmas[3] будет массив с номерами записей.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2821
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 19:29. Заголовок: Pasha Да но KMCOD н..


Pasha
Да но KMCOD на разных записях может быть одинаковый , поэтому так не годится.
Смысл затеи прост. Из заполненного hash массива быстро выбрать нужные Recno() и сложить в массив.
Например нужно выбрать всех клиентов у которых код торгового агента KMCOD равен 5 или скажем
выбрать всех клиентов у которых код группы CODGR равен 7.
Хотелось сделать универсальный хэш массив (для разного рода выборок для фильтра) и такой
массив я как бы создал но поиск по нему оставляет желать лучшего по времени. Хотя результат
500 мс для размера массива 700 000 записей тоже не плох. Имея массив с номерами записей
BM фильтр ставится в лет. Сейчас такой массив записей я заполняю иначе (юзаю нужный ордер
и заполняю массив). Думалось что с хэш массивом будет быстрее так как не надо лишний раз дергать
базу.

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2772
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 20.03.13 19:35. Заголовок: Dima пишет: Да но K..


Dima пишет:

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



Как раз именно так и годится. Значением hmas[kmcod] будет не один номер записи, а массив recno(). И поиск в этом hmas по значению kmkod будет мгновенным.
А одним хеш для всех случаев не обойдешься. Если выборки нужны по нескольким параметрам, то надо и делать несколько хеш-массивов, каждый для своего случая.
Смысл использования хеш только в мгновенном поиске. Использовать хеш, чтобы затем делать цикл по нему для поиска бессмыссленно.

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2773
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 20.03.13 19:40. Заголовок: Дима, если работать ..


Дима, если работать с хеш непривычно, я могу выложить свои функции для отсортированных массивов. Мне надо только причесать свой код, тот вариант, что я выкладывал раньше, не сохранился.
Суть примерно та же, что и хеш, только выглядит несколько нагляднее.
К тому же, как выяснилось, при добавлении в хеш по умолчанию не оптимизировано выделение памяти. А у AADD с этим все в порядке.


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2822
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 19:41. Заголовок: Pasha пишет: Смысл ..


Pasha пишет:

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


Это я уже понял и подумаю над твоей идеей. Спасибо

Pasha пишет:

 цитата:
Если нужны только номера записей, можно добавлять только recno()


Да я это понял. Спасибо. Обдумываю.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2823
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 19:44. Заголовок: Pasha пишет: К тому..


Pasha пишет:

 цитата:
К тому же, как выяснилось, при добавлении в хеш по умолчанию не оптимизировано выделение памяти


я пока делаю так hb_hAllocate( hms, Lastrec() ) и все нормально по скорости добавления.
Pasha пишет:

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


Было бы не плохо и это сильно и не горит , хочу еще сам поиграться с хеш массивами.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 173
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 20.03.13 21:09. Заголовок: Pasha пишет:тот вари..


Pasha пишет:
 цитата:
тот вариант, что я выкладывал раньше, не сохранился.


Это, наверно, они. http://zalil.ru/34366220

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2824
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 21:30. Заголовок: Pasha пишет: тот ва..


Pasha пишет:

 цитата:
тот вариант, что я выкладывал раньше, не сохранился.


да он где то есть на форуме я не давно натыкался на эту тему , нужно пошукать немного.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 174
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 20.03.13 21:38. Заголовок: Pasha пишет:А одним ..


Pasha пишет:
 цитата:
А одним хеш для всех случаев не обойдешься. Если выборки нужны по нескольким параметрам, то надо и делать несколько хеш-массивов, каждый для своего случая.


Как это будет выглядеть применительно к Leto ? "несколько хеш-массивов" надо пополнять или создавать заново ?
С предложенным способом от Dima понятно, при загрузке программы создал такой hash и работаю, на клиенте относительно него, пополняя его при LastRec > len(hmas) до потери пульса.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2826
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 22:24. Заголовок: SergKis пишет: попо..


SergKis пишет:

 цитата:
пополняя его при LastRec > len(hmas) до потери пульса


И меня та же идея посещала , но LETO пока не юзаю (поигрался малость - ПОНРАВИЛОСЬ) и перевожу прогу с Clipper на Harbour CDX а потом будет и LETO и вопросов будет видимо много.
Ты еще не забывай что такой массив еще нужно корректировать и иметь реакцию на удаление записей с учетом что все
это может происходить в сети ;)
Вообще при таком подходе либо держать нужно кучку hash массивов и юзать BM фильтра или
иметь такую же кучку дополнительных индексов (тегов) и юзать SCOPE. И там и там есть свои
и плюсы и минусы , в прочем это смотря какая задача и как все там организовано.
На вкус и цвет как говорится , товарищей нет


SergKis пишет:

 цитата:
пополняя его при LastRec > len(hmas) до потери пульса


Как славно что не нужно делать вот такой проверки , да и хэш массивов нет в clipper;)
 
if len(hmas)<4096

else

endif


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 175
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 21.03.13 08:20. Заголовок: Dima пишет:Вообще пр..


Dima пишет:
 цитата:
Вообще при таком подходе либо держать нужно кучку hash массивов


Проще работать с dbf MemIO или даже локальным dbf с полями, обеспечивающими быстрый доступ для создания нужных tag-ов и для переключения просмотров browse. С таблицей сервера relation по recno. Для обеспечения секретности можно поля обезличить (типа R_1,R_2,...) или что-то еще. Сейчас через MemIO примерно так делаем, только не весь dbf, а через запросы. Тоже пока без сервера- процесс перевода с Clipper на cdx в разгаре, потом Leto.
Dima пишет:
 цитата:
Ты еще не забывай что такой массив еще нужно корректировать и иметь реакцию на удаление записей с учетом что все это может происходить в сети ;)


В локальном dbf все записи, с учетом удаленных и только ключевые, не изменяемые поля. На сервере можно включит триггер, заполняющий поле типа TimeStamp (или символьное DtoS(Date())+StrTran(Time(), ":", "")+right(hb_ntos(bk_MilliSeconds()), 3)), для запросов по изменениям ...


Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2775
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 21.03.13 10:04. Заголовок: SergKis пишет: Как ..


SergKis пишет:

 цитата:
Как это будет выглядеть применительно к Leto ?



Если использовать Leto, то надо возложить функцию формирования bm-фильтра на сервер. Зачем гонять данные с сервера на клиент, формировать на клиенте массив с номерами записей и затем гнать обратно этот массив на сервер ? Зачем тогда такой сервер нужен ?

Сейчас в BMDBF* по set filter массив с номерами записей и так формируется, но это делается без учета scope. Можно исправить этот недостаток. Я вижу 3 пути для этого:

1) Убедить харбор-сообщество сделать это прямо в харборе (пока не получилось).
2) Скопировать сырцы BMDBF* в letodb и внести в них нужные изменения.
3) Сделать в letodb rdd - наследника BMDBF* и переписать в нем метод SetFilter (это сложнее).

Ну и наконец, можно на сервере просто добавить функцию, которой вы передавались параметры:
имя тэга, scope, filter, и эта функция сама бы формировала bm-фильтр по этим данным

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2830
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 21.03.13 10:18. Заголовок: Pasha Поддерживаю в..


Pasha
Поддерживаю вариант 2 и "можно на сервере просто добавить функцию"

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 177
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 21.03.13 11:08. Заголовок: Dima пишет:Поддержив..


Dima пишет:
 цитата:
Поддерживаю вариант 2 и "можно на сервере просто добавить функцию"


Тоже

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 178
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 21.03.13 11:34. Заголовок: Pasha пишет:Ну и нак..


Pasha пишет:
 цитата:
Ну и наконец, можно на сервере просто добавить функцию, которой вы передавались параметры: имя тэга, scope, filter, и эта функция сама бы формировала bm-фильтр по этим данным


Можно было бы обойтись этим, но тогда
If rddname() == 'LETO'
leto_setBmFilter(Tag,Scopr,Filter)
Else
dbSetFilter(...)
Endif
тоже как то ...

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2778
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 21.03.13 21:59. Заголовок: Добавил на сервере l..


Добавил на сервере letodb функцию LBM_DbSetFilter

Вызов функции с клиента:
leto_ParseRec( leto_Udf('LBM_DbSetFilter', <xScope>, <xScopeBottom>, <xOrder>, <cFilter>, <lDeleted> ) )
Функция устанавливает bitmap-фильтр по условиям scope, filter, и возвращает буфер с первой записью, удовлетворяющей условию фильтра

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2858
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 22.03.13 22:02. Заголовок: Pasha пишет: LBM_D..


Pasha пишет:

 цитата:
LBM_DbSetFilter


проясни плиз.
если активным является ордер 2 , но в LBM_DbSetFilter я указал xOrder равным 5 , какой
ордер будет активным после установки LBM_DbSetFilter ?
Должен быть 2 , что то не увидел я в сырцах возврата на прежний индекс после установки
LBM_DbSetFilter.

Сейчас я ставлю простой фильтр когда SCOPETOP и SCOPEBOTTOM равны вот так.
Прежний ордер остается на месте в любом случае после выполнения XbmFilter.
 
func XbmFilter(nseaord,xsea,myblock)
local ret:=.t.
local old_ord:=indexord()
local old_rec:=recno()
local afilt:={}
default myblock to nil

dbclearfilter()

dbsetorder(nseaord)
if dbseek(xsea)
dbOrderInfo(DBOI_SCOPEBOTTOM,,, xsea)
dbeval({|| aadd(afilt,recno())},myblock,,,,.t.)
dbOrderInfo(DBOI_SCOPEBOTTOMCLEAR)
endif
dbsetorder(old_ord)

if len(afilt)>0
BM_DBSETFILTERARRAY(afilt)
go top
else
ret:=.f.
dbgoto(old_rec)
endif
return ret




Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2783
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 23.03.13 01:06. Заголовок: На сервере нет инфор..


На сервере нет информации о том, какой управляющий индекс у клиента. Поэтому в каждой команде, которая поступает с клиента (для которой это конечно необходимо), должен быть прямо указан индекс.
Следовательно, серверу нет необходимости возвращать прежний индекс.
Поэтому не должно быть такой ситуации, когда управляющий индекс на клиенте один, а LBM_DbSetFilter получает другой.
Чтобы избежать этого, я на клиенте добавил функцию, у которой всего 3 параметра:

LBM_DbSetFilter( <xScope>, <xScopeBottom>, <cFilter> )

При этом серверу автоматически передается текущий индекс.

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 44 , стр: 1 2 3 All [только новые]
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 27
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет