Кстати, можно все функции переписать на PowerBASIC или Delphi, оформить в DLL и вызывать из Excel, тогда быстродействие будет в десятки раз выше VBA.
Наберитесь терпения, всему свое время, именно над этим я сейчас и работаю, причем не только на Delphi, но часть кода будет сделана на ассеблере, так что будет еще быстрей, чем вы думайте.
Хотя некоторые ограничения самой среды эксель все равно останутся, тут уж ни чего не поделаешь.
Последний раз редактировалось LordWilex, 19.01.2010 в 05:26.
А если все таки в VBA, то я бы посоветовал избавиться от типа Variant и заменить на Integer или Long
Там Variant'а очень мало, и то в тех местах, где не подразумеваются сложные вычисления.
К тому же, не поможет, т.к. среда эксель это вам не полноценный компилятор VB, так что данные из ячеек в функцию по любому передаются в варианте, а потом в зависимости от контекста переводятся в тот или иной тип
А разве на ассемблере будет намного быстрей чем C++? не проще ли будет сделать на C++?
А вы видели ассемблеровский код для математических функций в современых компиляторах?
На пример, простой синус вычисляется примерно так:
Цитата:
LOCAL content[108] :BYTE
LOCAL tempst :TBYTE
test uID,SRC1_FPU ;is Src taken from FPU?
jz continue
;-------------------------------
;check if top register is empty
;-------------------------------
fxam ;examine its content
fstsw ax ;store results in AX
fwait ;for precaution
sahf ;transfer result bits to CPU flag
jnc continue ;not empty if Carry flag not set
jpe continue ;not empty if Parity flag set
jz srcerr1 ;empty if Zero flag set
continue:
fsave content
;----------------------------------------
;check source for Src and load it to FPU
;----------------------------------------
test uID,SRC1_FPU ;is Src taken from FPU?
jz @F
lea eax,content
fld tbyte ptr[eax+28]
jmp dest0 ;go complete process
@@:
mov eax,lpSrc
test uID,SRC1_REAL ;is Src an 80-bit REAL in memory?
jz @F
fld tbyte ptr [eax]
jmp dest0 ;go complete process
@@:
test uID,SRC1_DMEM ;is Src a 32-bit integer in memory?
jz @F
fild dword ptr [eax]
jmp dest0 ;go complete process
@@:
test uID,SRC1_DIMM ;is Src an immediate 32-bit integer?
jz srcerr ;no correct flag for Src
fild lpSrc
jmp dest0 ;go complete process
srcerr:
frstor content
srcerr1:
xor eax,eax
ret
dest0:
test uID,ANG_RAD
jnz @F ;jump if angle already in radians
fldpi ;load pi (3.14159...) on FPU
fmul
pushd 180
fidiv word ptr[esp] ;value now in radians
fwait
pop eax ;clean the stack
@@:
fldpi
fadd st,st ;->2pi
fxch
@@:
fprem ;reduce the angle
fsin
fstsw ax ;retrieve exception flags from FPU
fwait
shr al,1 ;test for invalid operation
jc srcerr ;clean-up and return error
sahf ;transfer to the CPU flags
jpe @B ;reduce angle again if necessary
fstp st(1) ;get rid of the 2pi
test uID,DEST_FPU ;check where result should be stored
jnz @F ;leave result on FPU if so indicated
mov eax,lpDest
fstp tbyte ptr[eax] ;store result at specified address
jmp restore
@@:
fstp tempst ;store it temporarily
restore:
frstor content ;restore all previous FPU registers
test uID,SRC1_FPU ;was Src taken from FPU
jz @F
fstp st ;remove source
@@:
test uID,DEST_FPU
jz @F ;the new value has been stored in memory
;none of the FPU data was modified
ffree st(7) ;free it if not already empty
fld tempst ;load the new value on the FPU
@@:
or al,1 ;to insure EAX!=0
ret
Хотя, можно сделать то же самое, но гораздо проще, всего в три строчки:
Цитата:
fld tbyte ptr [eax]
fsin
fstp tbyte ptr[eax]
Конечно, для функций которые напрямую вызываются в экселевскую ячейку нет ни какой разницы на чем они написаны, экселевская среда будит их тормозить одинаково сильно
Но я планирую реализовать кое какие вещи, которые будут работать внутри самой DLL'ки и требуют большого количества итераций, на пример генетические алгоритмы, и другие способы оптимизации если руки дойдут, и там будут такие задачи, когда, на пример, нужно за короткое время 1 000 000 раз вычислить юлианскую дату и тут каждый такт процессора будет на счету, так что при всем богатстве выбора другой альтернативы нету
LordWilex, если вы будете делать на Delphi то ассемблерные вставки лучше сделать в виде отдельных функций, тогда быстродействие будет еще лучше
Если ASM код будет в отдельной функции, то параметры будут передаваться через регистры процессора, отсюда и увеличение производительности
LordWilex, если вы будете делать на Delphi то ассемблерные вставки лучше сделать в виде отдельных функций, тогда быстродействие будет еще лучше
Если ASM код будет в отдельной функции, то параметры будут передаваться через регистры процессора, отсюда и увеличение производительности
Виталь, такое дело... ты мог бы на досуге добавить процедуру расчета азимута и высоты планет? Буду весьма признателен )
Конечно сделаем, не вопрос!!!
Все это вшито в сами ШЭ, нужно только сделать так, чтобы это вызывалось через VB, думаю за минут сделаю, просто не думал, что это кому-нить понадобиться, поэтому и не делал.
Только с компом проблемы решу, пару деньков подожди, а то я ща под линуксом, а тут эксели нету
Все это вшито в сами ШЭ, нужно только сделать так, чтобы это вызывалось через VB, думаю за минут сделаю, просто не думал, что это кому-нить понадобиться, поэтому и не делал.
Только с компом проблемы решу, пару деньков подожди, а то я ща под линуксом, а тут эксели нету
Кстати, есть же неофициальный порт ШЭ под Java, может его можно как нибудь на C# или J# переделать?, тогда если писать на C#, никаких DLL не нужно будет...
Кстати, есть же неофициальный порт ШЭ под Java, может его можно как нибудь на C# или J# переделать?, тогда если писать на C#, никаких DLL не нужно будет...
Ну теоретически можно попробовать это сделать, тем более есть конвекторы кода с С на С#, правда нет ни какой гарантии, что преобразование пройдет без ошибок в коде только какой в этом смысл, и чем вас dll не устраивает?
ШЭ распространяются с полностью открытым исходным кодом, и нет ни каких проблем, чтобы использовать его в своих прогах напрямую без всяких DLL
Проблемы возникают, если пишешь на дельфи и не хочешь юзать DLL'ки, но и тут есть куча обходных путей
....или, возможно, я вас не так понял