Nenad Batoćanin <nbato...@wings.rs>: Mar 23 12:17AM +0100
If anyone remembers the CA Visual Objects project... It had a very nice object-oriented approach to working with the database. It looks like this:
oDb := DBServer ("Test")
oDb:SetIndex ("Test_ID")
WHILE ! oDb:Eof()
IF oDb:Id == 0
oDb:Id := RecNo()
oDb:Name := "None"
END IF
oDb:Skip()
END DO
I believe this code is clear to everyone :) The really good thing is that almost identical code could also work with SQL Server. Only the initialization was a little different:
oDb := SQLSelect ("SELECT * FROM Test ORDER BY Id")
Regards, NB
From: harbou...@googlegroups.com <harbou...@googlegroups.com> On Behalf Of Francesco Perillo
Sent: nedelja, 22. mart 2026. 17:41
To: harbou...@googlegroups.com
Subject: Re: [harbour-users] Refactoring legacy code to OOP — class/object access 5–7× slower than array
Yes, of course. Perhaps HASH but I don't know how they are implemented internally.
But you are right, there should be a way for a better ram storage:
- one possibility is to create a new algorithm, in C of course, to create a sort of index, like a....
- NTX/CDX index... so it may be interesting to copy the 3 files in ram and create the indexes.
We lack important informations...
Il Sab 21 Mar 2026, 23:20 'Nenad Batoćanin' via Harbour Users <harbou...@googlegroups.com <mailto:harbour-users@googlegroups.com> > ha scritto:
Hi!
I think AScan does a simple sequential search, so it can't be as fast as index search. Perhaps a replacement for AScan could be made that uses a memory table and a seek search?
Regards, NB
From: harbou...@googlegroups.com <mailto:harbour-users@googlegroups.com> <harbou...@googlegroups.com <mailto:harbour-users@googlegroups.com> > On Behalf Of Francesco Perillo
Sent: subota, 21. mart 2026. 21:58
To: harbou...@googlegroups.com <mailto:harbour-users@googlegroups.com>
Subject: Re: [harbour-users] Refactoring legacy code to OOP — class/object access 5–7× slower than array
I was having a second look at your code and I still think that using objects is not the way to go.
Also, you are not providing informations on the relationships of the records, one-to-one, one-to-many, many-to-many... the code seems to be a one-to-one
Without more informations it is difficult to give some clues, but I ask you, out of curiosity, to change the code in this way and report if there is a speed improvement
The new code explicitely uses local variables in the aScan codeblock; I don't know if Harbour optimizes oHdr:code+oHdr:key
LOCAL cKH, cKD
FOR EACH oHdr IN aHeader // ~1,000 records
cKH := oHdr:code + oHdr:key
nn := AScan(aDetails, {|x| x:code+x:key = cKH }) // ~3,000 records total
IF nn > 0
oDtl := aDetails[nn]
cKD := oDtl:code + oDtl:key
kk := AScan(aSubs, {|x| x:code+x:key = cKD }) // ~5,000 records total
IF kk > 0
oDtl := aSubs[kk]
// read properties, compute, output
ENDIF
ENDIF
NEXT
FOR EACH oHdr IN aHeader // ~1,000 records
nn := AScan(aDetails, {|x| x:code+x:key = oHdr:code+oHdr:key }) // ~3,000 records total
IF nn > 0
oDtl := aDetails[nn]
kk := AScan(aSubs, {|x| x:code+x:key = oDtl:code+oDtl:key }) // ~5,000 records total
IF kk > 0
oDtl := aSubs[kk]
// read properties, compute, output
ENDIF
ENDIF
NEXT
Any guidance from those who have done similar legacy refactoring
projects would be greatly appreciated.
Thank you,
Atul Parate
--
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
Unsubscribe: harbour-user...@googlegroups.com <mailto:harbour-users%2Bunsubscribe@googlegroups.com>
Web: https://groups.google.com/group/harbour-users
---
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to harbour-user...@googlegroups.com <mailto:harbour-users+unsubscribe@googlegroups.com> .
To view this discussion visit https://groups.google.com/d/msgid/harbour-users/947f4824-e06d-4d4e-aa9c-5ff689cb99f0n%40googlegroups.com <https://groups.google.com/d/msgid/harbour-users/947f4824-e06d-4d4e-aa9c-5ff689cb99f0n%40googlegroups.com?utm_medium=email&utm_source=footer> .
--
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
Unsubscribe: harbour-user...@googlegroups.com <mailto:harbour-users+unsubscribe@googlegroups.com>
Web: https://groups.google.com/group/harbour-users
---
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to harbour-user...@googlegroups.com <mailto:harbour-users+unsubscribe@googlegroups.com> .
To view this discussion visit https://groups.google.com/d/msgid/harbour-users/CADPHLr9RmwyV7Gca1zGtUyudF0JCNuM%3DW04EvP2VvEX7Errwsw%40mail.gmail.com <https://groups.google.com/d/msgid/harbour-users/CADPHLr9RmwyV7Gca1zGtUyudF0JCNuM%3DW04EvP2VvEX7Errwsw%40mail.gmail.com?utm_medium=email&utm_source=footer> .
--
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
Unsubscribe: harbour-user...@googlegroups.com <mailto:harbour-users%2Bunsubscribe@googlegroups.com>
Web: https://groups.google.com/group/harbour-users
---
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to harbour-user...@googlegroups.com <mailto:harbour-users+unsubscribe@googlegroups.com> .
To view this discussion visit https://groups.google.com/d/msgid/harbour-users/008601dcb980%24ecd55a70%24c6800f50%24%40wings.rs <https://groups.google.com/d/msgid/harbour-users/008601dcb980%24ecd55a70%24c6800f50%24%40wings.rs?utm_medium=email&utm_source=footer> .
--
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
Unsubscribe: harbour-user...@googlegroups.com <mailto:harbour-users+unsubscribe@googlegroups.com>
Web: https://groups.google.com/group/harbour-users
---
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to harbour-user...@googlegroups.com <mailto:harbour-users+unsubscribe@googlegroups.com> .
To view this discussion visit https://groups.google.com/d/msgid/harbour-users/CADPHLr-OJcJniJq7XKDmy%3D7xfdW_GxBGP4JoYLa9WXG0co32PQ%40mail.gmail.com <https://groups.google.com/d/msgid/harbour-users/CADPHLr-OJcJniJq7XKDmy%3D7xfdW_GxBGP4JoYLa9WXG0co32PQ%40mail.gmail.com?utm_medium=email&utm_source=footer> .
|
Mario H. Sabado <mhsa...@gmail.com>: Mar 23 01:30PM +0800
Hi Atul,
Not an OOP sample but I have come up with this approach when I have a need
to export a DBF file with over ~21M records to CSV. I need to process each
line as an array because of some necessary data conversion before saving to
the final CSV. I also tried the FOR/While combination approach but it's
over 10X slower than AEval() in my case scenario.
Below is my code snippet based on my understanding of your case.
Best regards,
Mario
*************************
function MasterDetailSubs
*************************
local xVal,yVal
local aHeader:={{"H1","H1 Header"},;
{"H2","H2 Header"},;
{"H3","H3 Header"} }
local aDetails:={{"H1","H1-Detail 1"},;
{"H1","H1-Detail 2"},;
{"H1","H1-Detail 3"},;
;
{"H2","H2-Detail 1"},;
{"H2","H2-Detail 2"},;
{"H2","H2-Detail 3"},;
;
{"H3","H3-Detail 1"},;
{"H3","H3-Detail 2"},;
{"H3","H3-Detail 3"} }
local aSubs :={ {"H1","H1-Detail 1","H1 D1 Sub 1"},;
{"H1","H1-Detail 1","H1 D1 Sub 2"},;
;
{"H1","H1-Detail 2","H1 D2 Sub 1"},;
{"H1","H1-Detail 2","H1 D2 Sub 2"},;
;
{"H1","H1-Detail 3","H1 D3 Sub 1"},;
{"H1","H1-Detail 3","H1 D3 Sub 2"},;
;
{"H2","H2-Detail 1","H2 D1 Sub 1"},;
{"H2","H2-Detail 1","H2 D1 Sub 2"},;
;
{"H2","H2-Detail 2","H2 D2 Sub 1"},;
{"H2","H2-Detail 2","H2 D2 Sub 2"},;
;
{"H2","H2-Detail 3","H2 D3 Sub 1"},;
{"H2","H2-Detail 3","H2 D3 Sub 2"},;
;
{"H3","H3-Detail 1","H3 D1 Sub 1"},;
{"H3","H3-Detail 1","H3 D1 Sub 2"},;
;
{"H3","H3-Detail 2","H3 D2 Sub 1"},;
{"H3","H3-Detail 2","H3 D2 Sub 2"},;
;
{"H3","H3-Detail 3","H3 D3 Sub 1"},;
{"H3","H3-Detail 3","H3 D3 Sub 2"} }
AEval(aHeader,{|x|Qout( (xVal:=x[1])+"-"+x[2] ), ; //Header
,AEval(aDetails,{|y| iif(xVal==y[1],Qout(yVal:=y[1]+y[2]), ) ;
//Detail
, AEval(aSubs,{|z| iif(xVal==z[1] .and.
yVal==z[1]+z[2], Qout( yVal+"-"+z[3]) , ) ; //Sub-Detail
}) ;
}) ;
})
return nil
/* SAMPLE OUTPUT
H1-Header 1
H1H1-Detail 1
H1H1-Detail 1-H1 D1 Sub 1
H1H1-Detail 1-H1 D1 Sub 2
H1H1-Detail 2
H1H1-Detail 2-H1 D2 Sub 1
H1H1-Detail 2-H1 D2 Sub 2
H1H1-Detail 3
H1H1-Detail 3-H1 D3 Sub 1
H1H1-Detail 3-H1 D3 Sub 2
H1H1-Detail 3-H1 D3 Sub 1
H1H1-Detail 3-H1 D3 Sub 2
H1H1-Detail 3-H1 D3 Sub 1
H1H1-Detail 3-H1 D3 Sub 2
H1H1-Detail 3-H1 D3 Sub 1
H1H1-Detail 3-H1 D3 Sub 2
H1H1-Detail 3-H1 D3 Sub 1
H1H1-Detail 3-H1 D3 Sub 2
H1H1-Detail 3-H1 D3 Sub 1
H1H1-Detail 3-H1 D3 Sub 2
H1H1-Detail 3-H1 D3 Sub 1
H1H1-Detail 3-H1 D3 Sub 2
H2-Header 2
H2H2-Detail 1
H2H2-Detail 1-H2 D1 Sub 1
H2H2-Detail 1-H2 D1 Sub 2
H2H2-Detail 2
H2H2-Detail 2-H2 D2 Sub 1
H2H2-Detail 2-H2 D2 Sub 2
H2H2-Detail 3
H2H2-Detail 3-H2 D3 Sub 1
H2H2-Detail 3-H2 D3 Sub 2
H2H2-Detail 3-H2 D3 Sub 1
H2H2-Detail 3-H2 D3 Sub 2
H2H2-Detail 3-H2 D3 Sub 1
H2H2-Detail 3-H2 D3 Sub 2
H2H2-Detail 3-H2 D3 Sub 1
H2H2-Detail 3-H2 D3 Sub 2
H3-Header 3
H3H3-Detail 1
H3H3-Detail 1-H3 D1 Sub 1
H3H3-Detail 1-H3 D1 Sub 2
H3H3-Detail 2
H3H3-Detail 2-H3 D2 Sub 1
H3H3-Detail 2-H3 D2 Sub 2
H3H3-Detail 3
H3H3-Detail 3-H3 D3 Sub 1
H3H3-Detail 3-H3 D3 Sub 2
*/
On Mon, Mar 23, 2026 at 7:17 AM 'Nenad Batoćanin' via Harbour Users <
|