Posting results and work in process for just the add function. Sample code fully goes from Jxints to BN garbage collected objects and back to a Jxint result. library attached at bottom. Uses a class based approach to facilitate memory management/cleanup, and inherritance for secure contexts, and managed code. Btw, one of the supposed benefits of BN over GMP is that it is more memory efficient
fibtest =: 3 : 0 'fibCtx' coassign '' conew 'bnctx' (codestroy__fibCtx@:(''"_) ] ,.@('toX a:'&inl)) MANAGED__fibCtx[(1 2 0{][BNadd__fibCtx)^:y '<I'inl newM__fibCtx 1 1 1 ) starts getting faster around 6000 iterations timespacex 'fibtest 10000' 0.0298173 61312 timespacex '({: , +/)^:(10000) 1 1x' 0.0367766 44928 timespacex 'fibtest 50000' 0.199689 157952 timespacex '({: , +/)^:(50000) 1 1x' 0.765411 167808 timespacex '({: , +/)^:(80000) 1 1x' 1.79307 331648 timespacex 'fibtest 80000' 0.370815 289024 As a stress test, sums with managed memory context sum =: 3 : 0 acc =. newM {: y toX__acc (}: y) 4 : 'y[ BNfree a [ BNadd I__y;I__y;a =. newI x' reduce acc ) timespacex '''sum'' withtemp_bnctx_ (0 ". ''x'',~ 990 # ''123'') + i.4530' 0.91709 7.73599e7 timespacex '''sum'' withtemp_bnctx_ i.4530' 0.227081 979072 timespacex '+/ (0 ". ''x'',~ 990 # ''123'') + i.4530' 0.0640345 3.80096e7 timespacex '+/ i.4530x' 0.00184256 747776 with manual context, the extra time saved is mostly large int copies into code C =. '' conew 'bnctx' timespacex 'sum__C (0 ". ''x'',~ 990 # ''123'') + i.4530' 0.813071 3.88996e7 timespacex 'sum__C i.4530' 0.243128 902016 an oop version is slow though, though almost tacit. addX function adds a J int to a BN. (stores in same BN) add stores in itself but needs a BN argument. The first function is useful for temp BN's as it autodestroys the number. sum3 =: 3 : 0 acc =. newM {: y toX__acc (}: y) addX__acc@[ reduce acc ) timespacex 'sum3__C i.4530' 0.679583 896896 codestroy__C '' timespacex '''sum3'' withtemp_bnctx_ i.4530' NB. memory managed version 0.688436 973952 A version that looks cleaner but uses more memory as it has to copy the pointer result for each element: sum4 =: 3 : 0 acc =. newM {. y toX__acc addX__acc"0 }.y ) timespacex 'sum4__C i.4530' 0.688726 3.38406e6 So, its fast when it doesn't need to create and destroy many BNs. I'm sure there are plenty of other areas where a useful speedup is obtained. I'll be adding more than add function. The OOP interface is completely bypassable, but is convenient. require 'dll' cocurrent 'ssl' sslp =: IFWIN pick '';'D:\OpenSSL-Win64\bin\' sslp =: IFWIN pick ''; '/',~ jpath '~bin' NB. with J802. cut this line if you wish to point to downloaded folder NB. OPENSSL =: jpath '~system/ssleay32.dll ' NB.OPENSSL =: sslp , '\ssleay32.dll ' OPENSSL =: sslp , (IFIOS + (;: 'Win Linux Android Darwin') i. <UNAME_z_) pick 'libeay32.dll '; (2 $ <'libssl.so.1.0.0 '), (2 $ <'/usr/lib/libssl.dylib ') NB.OPENSSL =: sslp , (IFIOS + (;: 'Win Linux Android Darwin') i. <UNAME_z_) pick 'libeay32.dll '; (2 $ <'libssl.so '); (2 $ <'libssl.0.9.8.dylib ') SSLE =: sslp , '\openssl' ssl =: 1 : '(OPENSSL , m)&cd' BNctxnew =: ' BN_CTX_new + x' ssl BNnew =: ' BN_new >+ x' ssl NB. probably don't use... unamanaged memory version. BNmul =: ' BN_mul + i *x *x *x *x' ssl NB. BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret) BN2bn =: ' BN_bin2bn + *x *c l *x' ssl NB. int BN_bn2bin(const BIGNUM *a, unsigned char *to) BN2bin =: ' BN_bn2bin + i x *c' ssl BN_bn2hex=: ' BN_bn2hex + c x ' ssl NB.char * BN_bn2hex(const BIGNUM *a); BN_hex2bn =: ' BN_hex2bn + i *x *c' ssl NB.(BIGNUM **a, const char *str); BNnum_bytes=: ' BN_num_bytes i *i' ssl NB. doest work as its macro? NB. int BN_num_bits(const BIGNUM *a) BN_num_bits=: ' BN_num_bits + i x' ssl num_bytes =: 0.125 <.@* BN_num_bits BN2dec=: ' BN_bn2dec >+ x x' ssl NB. char *BN_bn2dec(const BIGNUM *num) dec2BN=: ' BN_dec2bn > + i *x *c' ssl NB. int BN_dec2bn(BIGNUM **num, const char *str) NB. BN_print(BIO *fp, const BIGNUM *a); BNfree =: ' BN_free + n x' ssl NB.BN_free(bn: pBIGNUM); cdecl BNclear_free=: ' BN_clear_free + n x' ssl NB.BN_free(bn: pBIGNUM); cdecl BNclear =: ' BN_clear + n x' ssl NB.BN_free(bn: pBIGNUM); cdecl BNCTX_free=: 'BN_CTX_free+ n x' ssl NB. void BN_CTX_free(BN_CTX *c); BNCTX_start =: 'BN_CTX_start+ n x' ssl NB.void BN_CTX_start(BN_CTX *ctx); BNCTX_end =: 'BN_CTX_end + n x' ssl BNdup =: ' BN_dup > + x x' ssl NB.BIGNUM *BN_dup(const BIGNUM *from); BNCTX_get =: ' BN_CTX_get > + x x' ssl NB. BIGNUM *BN_CTX_get(BN_CTX *ctx); BNcopy =: ' BN_copy > + x x x' ssl NB.BIGNUM *BN_copy(BIGNUM *to, const BIGNUM *from); BNswap =: ' BN_swap > + x x x' ssl BNadd =: ' BN_add > + i x x x' ssl NB.int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) NB. coclass 'OOP' NB. OOP_z_ =: <'OOP' NB. Cbase =: <'base' NB. coclass_z_ =: 18!:4@boxxopen@:[ ((('_OOP_' ,~ 'C' , ]) assign boxopen)^:(0 = L.)) NB. coclass =: 18!:4@boxxopen@:[ ((('_OOP_' ,~ 'C' , ]) assign (][ coerase)@:boxopen)^:(0 = L.)) cocurrent 'z' pD_z_ =: 1!:2&2 cders_z_ =: cder ; cderx coself_z_ =: coname@(''"_) codestroy =: (coerase@coname@(''"_) ] destroy :: ])"0 coinsert=: 3 : 0 n=. ;: :: ] y p=. ; (, 18!:2) @ boxopen each n p=. ~. ( 18!:2 coname''), p (p /: p = <,'z') 18!:2 coname'' ) inl_z_ =: (cocurrent@] ".@] [)"1 0 inlC_z_ =: 2 : 0 (([: <^:(0=L.) v"_) inl~ m , ' ', lr@:]) : (([: <^:(0=L.) v"_) inl~ (lr@:[), ' ' ,m , ' ', lr@:] ) ) inlA_z_ =: 1 : 'u inlC (18!:5 '''')' coassign_z_ =: 4 : 0 NB.y is object or list of objects. x is string name try. (coerase ] 'destroy a:'&inl :: ]) x~ catch. end. (x) =: y ) lr_z_ =: 3 : '5!:5 < ''y''' loc =: (,&'_'@[ ,&'_'@, ":@>@])"1 0 locs =: 1 : 'm loc 18!:5 ''''' eval_z_ =: 1 : ' a: 1 : m' reduce =: 1 : '<"_1@[ ([: u &.>/(>@:) ,) <@:]' coclass 'bnctx' MANAGED =: i. 0 0 coinsert 'ssl' create =: 3 : 0 CTX =: BNctxnew 0{.a. ) withtemp =: 1 : 0 NB.creates new ctx that will execute u then destroy itself u incontext withtemp 'tmpCtx' coassign a: conew 'bnctx' NB.('[: (] [', ' destroy' locs__tmpCtx , ') ' , u lrA inlA__tmpCtx lrA )eval ('[: (] [', ' destroy' locs__tmpCtx , ') ' , m inlA__tmpCtx lrA)eval ) NB. FUNCTIONS ON BNs new =: 3 : 'a [ (''coinsert '', lr coself a:) inl a=.''bn'' conew"0 1~ y' newI =: 3 : 'create_bn_ y' NB. need to manually release, but no object at all. newM =: 3 : 'a [ (''coinsert '', lr coself a:) inl a [ MANAGED =: MANAGED , a=.''bn'' conew"0 1~ y' NB. appends BN in public list. autodestroyed on destroy this. dup =: 3 : 'a [ coinsert__a coself a: [ a =. dup__y' NB. just 1 BN. not list. kill=: 3 : 'codestroy__y a:' NB. just 1 BN. NB. incontext =: 1 : 0 NB. u is dyad, has access to faster autoreleased gets instead of new. NB. ('BNCTX_end_ssl_@(CTX"_) ] [(' , m , ' :: ((cders ; 13!:11 ; 13!:12 )@:(''''"_))) ][ BNCTX_start_ssl_@(CTX"_)') eval NB. ) get =: 3 : 'BNCTX_get@(CTX"_)' NB. not object and not managed. newGM =: 3 : 'a [ MANAGED =: MANAGED , a=. new_bnget_"_ 0 y' NB. requires an incontext adverb surrounding call. sum2 =: 3 : 0 NB. slow and mem hog demo acc =. newM {: y toX__acc (}: y) ( [: add__acc newM@[) reduce acc ) sum =: 3 : 0 acc =. newM {: y toX__acc (}: y) 4 : 'y[ BNfree a [ BNadd I__y;I__y;a =. newI x' reduce acc ) sum3 =: 3 : 0 acc =. newM {: y toX__acc (}: y) (][ [: addX__acc [) reduce acc ) clearmanaged =: 'MANAGED'&coassign destroy =: 3 : 'clearmanaged i.0 0 [ BNCTX_free :: ] CTX ' NB. CTX_free may not exist cocurrent 'bn' coinsert 'ssl' create =: 3 : 0 I =: BNnew 0{.a. NB.pD Ia =: 15!:6 <'I' initlen =. dec2BN (,I);(": y) assert. initlen > 0 I ) todec =: 3 : 0 o =. BN2dec I memr o,0 _1 2 ) toX =: 0 ". 'x' ,~ todec Dbn_z_ =: 3 : 'todec__y a:' Xbn_z_ =: 3 : 'toX__y a:' dup =: 3 : 0 b =. conew 'bn' I__b =: BNdup I b ) add =: 3 : 0 NB. adds self to y (bn object) i =.BNadd I;I;I__y coself a: ) addX =: 3 : 0 a =. newI y i =.BNadd I;I;a BNfree a coself a: ) destroy =: 3 : 0 BNfree I 1 ) coclass 'base' NB. (][BNadd__C)^:1000 I__a;I__a;I__a NB. FIBONACI full cycle fibtest =: 3 : 0 'fibCtx' coassign '' conew 'bnctx' (codestroy__fibCtx@:(''"_) ] ,.@('toX a:'&inl)) MANAGED__fibCtx[(1 2 0{][BNadd__fibCtx)^:y '<I'inl newM__fibCtx 1 1 1 ) ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm