Hi all, I'm refactoring my code and I found that I have two ways to do the same in distint parts of my system. 1) Entity class >> atCode: aCode "Answer the receiver instance with code equal to aCode or evaluate aBlock if it doesn't exists."
^(self all detect: [:one | one code = aCode]) copy or 2) Entity class>> atCode: aCode inSession: anUserSession "Answer the receiver instance with code equal to aCode or evaluate aBlock if it doesn't exists."
^(self allInSession: anUserSession) detect: [:one | one code = aCode] The difference is that 1 is using the shared session so I need copy the object to be used (referenced by other object) on anUserSession. The uggly of 2 is that I have to pass anUserSession as argument.
Either way works well, is really the same? Thanks in advance, Facu (*) I eliminate aBlock for absent elements for this example
_______________________________________________ Magma mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/magma |
I'm not sure I fully understand the context, but a third option might
be to use ForwardingProxies. Especially if the shared objects can be updated by only one session (like a batch updater, for example). Then every other (user client) session will share the same instances in memory. HTH, Chris On Wed, Dec 8, 2010 at 1:13 PM, Facundo Vozzi <[hidden email]> wrote: > Hi all, > I'm refactoring my code and I found that I have two ways to do the same in > distint parts of my system. > 1) Entity class >> atCode: aCode > "Answer the receiver instance with code equal to aCode or evaluate aBlock if > it doesn't exists." > ^(self all detect: [:one | one code = aCode]) copy > or > 2) Entity class>> atCode: aCode inSession: anUserSession > "Answer the receiver instance with code equal to aCode or evaluate aBlock if > it doesn't exists." > > ^(self allInSession: anUserSession) detect: [:one | one code = aCode] > The difference is that 1 is using the shared session so I need copy the > object to be used (referenced by other object) on anUserSession. The uggly > of 2 is that I have to pass anUserSession as argument. > Either way works well, is really the same? > Thanks in advance, > Facu > (*) I eliminate aBlock for absent elements for this example > _______________________________________________ > Magma mailing list > [hidden email] > http://lists.squeakfoundation.org/mailman/listinfo/magma > > Magma mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/magma |
I'll read about ForwardingProxies because I didn't use it yet.
To clarify the context, I'm bulk load transactions from a csv file, so I proccess the file and create each transactions in the user session and I need referencing system entities (operationsTypes, etc) from their codes or names (atCode:) but for do that or I need pass the user session by argument or do a copy to the entity from the shared session. Can you understand my poor english explanation now?
Thanks for your help, Facu
On Thu, Dec 9, 2010 at 4:35 PM, Chris Muller <[hidden email]> wrote: I'm not sure I fully understand the context, but a third option might _______________________________________________ Magma mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/magma |
Now I'm getting a performance problem. I'm bulk loading transactions in sets (from a file) of 1250. Each of one has references to 3 objects, 3 numbers and 2 dates. When I test it without setting the customer it take to me 614 milliseconds to create the 1250 instances but if I look up for each client according to the client code it take to me 204158 milliseconds (3.40 minutes).
Customers is a MagmaCollection and this is the method of the message that I'm sending 1250 times: customerAtDocumentNumber: unString sex: otroString "Devuelve un invividuo o una organizacion dependiendo de si unString corresponde a un número de documento o a un número de cuit. NOTA: se debe tener en cuenta el sexo por existir números de dni repetidos entre varones y mujeres."
| aFewCustomers | aFewCustomers := self customers where: [ :each | (each documentNumber = unString)].
^customers detect: [:each | each documentNumber = unString and: [each sex = otroString]] ifNone: []
Customers has an index on documentNumber. Now I go to profile it but I need to find how to do it in Pharo. I thing that I can switch customers from MagmaCollection to MagmaDictionary and set the document number + sex how the key. What do you think?
See you, Facu On Thu, Dec 9, 2010 at 7:36 PM, Facundo Vozzi <[hidden email]> wrote:
_______________________________________________ Magma mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/magma |
Yes, I'm not surprised that takes 3 minutes. The first problem is
that you are using an invalid operator in your where. You must use "equals:", not "=". But the bigger problem is the design. There is overhead to using #where:, especially when using a disjuction or sorting or eliminating duplicates. End-user search and querying is the primary use-case for the #where: operations, not using Magma as a RDBMS to "look-up" single objects by a key value. The right collection for that job is MagmaPreallocatedDictionary, which can be large (millions) and still provide very fast #at: access to one object at a time. I do not recommend MagmaDictionary or MagmaSet where performance is at all concerned. For that reason these collections really deserve to be deprecated and deleted from Magma. The right way to use Magma is to do things as object-oriented as possible, and only rely on MagmaCollections for applying value-indexing to the objects. Is documentNumber extrinsic to the system, or is it a relational pointer to a Document object? Regards, Chris On Thu, Dec 9, 2010 at 5:47 PM, Facundo Vozzi <[hidden email]> wrote: > Now I'm getting a performance problem. > I'm bulk loading transactions in sets (from a file) of 1250. Each of one has > references to 3 objects, 3 numbers and 2 dates. > When I test it without setting the customer it take to me 614 milliseconds > to create the 1250 instances but if I look up for each client according to > the client code it take to me 204158 milliseconds (3.40 minutes). > Customers is a MagmaCollection and this is the method of the message that > I'm sending 1250 times: > customerAtDocumentNumber: unString sex: otroString > "Devuelve un invividuo o una organizacion dependiendo de si unString > corresponde a un número de documento o a un número de cuit. NOTA: se debe > tener en cuenta el sexo por existir números de dni repetidos entre varones y > mujeres." > | aFewCustomers | > aFewCustomers := self customers where: [ :each | (each documentNumber = > unString)]. > ^customers detect: [:each | each documentNumber = unString and: [each sex = > otroString]] ifNone: [] > > > Customers has an index on documentNumber. Now I go to profile it but I need > to find how to do it in Pharo. > I thing that I can switch customers from MagmaCollection to MagmaDictionary > and set the document number + sex how the key. What do you think? > See you, > Facu > > On Thu, Dec 9, 2010 at 7:36 PM, Facundo Vozzi <[hidden email]> wrote: >>> >>> >>> If you do a copy, then you will be creating multiple instances of >>> various "system entities", which I'm guessing don't want to do; you >>> would rather have just one instance, referenced from multiple >>> transactions, right? >> >> Yes, you're right I don't want multiple instances. >>> >>> So all you need to do is just look-up the *equivalent* Code in session >>> which is doing the loading. It will be the one identical instance in >>> the repository. >> >> Yes, to do that I'm passing the session which is doing the loading by >> argument. But I think that my error here is that I'm implementing the >> protocol to get one entitiy instance by code or name on the Entity class >> side. I think is >> better implement it, by example #clientOfCode: aCode, in my system >> instance >> which is the root of each session. In this manner I don't need pass the >> user session by argument. I think that my traditional database mapping >> thinking betrayed me >>> >>> But yes, this is one of the use-cases for which FP's were invented, it >>> can be a more elegant solution, especially if the number of Codes is >>> always changing or increasing. See >>> MagmaTestCase>>#testForwardingProxy. >> >> Yes, I will see it right now. >> Facu >> >>> >>> - Chris >>> >>> >>> > Thanks for your help, >>> > Facu >>> > >>> > On Thu, Dec 9, 2010 at 4:35 PM, Chris Muller <[hidden email]> >>> > wrote: >>> >> >>> >> I'm not sure I fully understand the context, but a third option might >>> >> be to use ForwardingProxies. Especially if the shared objects can be >>> >> updated by only one session (like a batch updater, for example). Then >>> >> every other (user client) session will share the same instances in >>> >> memory. >>> >> >>> >> HTH, >>> >> Chris >>> >> >>> >> On Wed, Dec 8, 2010 at 1:13 PM, Facundo Vozzi <[hidden email]> >>> >> wrote: >>> >> > Hi all, >>> >> > I'm refactoring my code and I found that I have two ways to do the >>> >> > same >>> >> > in >>> >> > distint parts of my system. >>> >> > 1) Entity class >> atCode: aCode >>> >> > "Answer the receiver instance with code equal to aCode or evaluate >>> >> > aBlock if >>> >> > it doesn't exists." >>> >> > ^(self all detect: [:one | one code = aCode]) copy >>> >> > or >>> >> > 2) Entity class>> atCode: aCode inSession: anUserSession >>> >> > "Answer the receiver instance with code equal to aCode or evaluate >>> >> > aBlock if >>> >> > it doesn't exists." >>> >> > >>> >> > ^(self allInSession: anUserSession) detect: [:one | one code >>> >> > = >>> >> > aCode] >>> >> > The difference is that 1 is using the shared session so I need copy >>> >> > the >>> >> > object to be used (referenced by other object) on anUserSession. The >>> >> > uggly >>> >> > of 2 is that I have to pass anUserSession as argument. >>> >> > Either way works well, is really the same? >>> >> > Thanks in advance, >>> >> > Facu >>> >> > (*) I eliminate aBlock for absent elements for this example >>> >> > _______________________________________________ >>> >> > Magma mailing list >>> >> > [hidden email] >>> >> > http://lists.squeakfoundation.org/mailman/listinfo/magma >>> >> > >>> >> > >>> > >>> > >> > > Magma mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/magma |
On 10 December 2010 02:59, Chris Muller <[hidden email]> wrote:
> Yes, I'm not surprised that takes 3 minutes. The first problem is > that you are using an invalid operator in your where. You must use > "equals:", not "=". But the bigger problem is the design. There is > overhead to using #where:, especially when using a disjuction or > sorting or eliminating duplicates. End-user search and querying is > the primary use-case for the #where: operations, not using Magma as a > RDBMS to "look-up" single objects by a key value. The right > collection for that job is MagmaPreallocatedDictionary, which can be > large (millions) and still provide very fast #at: access to one object > at a time. I do not recommend MagmaDictionary or MagmaSet where > performance is at all concerned. For that reason these collections > really deserve to be deprecated and deleted from Magma. > Whis makes me think that the problem lying in API. I think that Magma could provide an API, which will let users to do thing in most efficient way, without much hassle. Especially for people with big RDBMS background (most of us ;). > The right way to use Magma is to do things as object-oriented as > possible, and only rely on MagmaCollections for applying > value-indexing to the objects. Is documentNumber extrinsic to the > system, or is it a relational pointer to a Document object? > > Regards, > Chris > > > -- Best regards, Igor Stasenko AKA sig. _______________________________________________ Magma mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/magma |
In reply to this post by fvozzi
On 10 December 2010 00:47, Facundo Vozzi <[hidden email]> wrote:
> Now I'm getting a performance problem. > I'm bulk loading transactions in sets (from a file) of 1250. Each of one has > references to 3 objects, 3 numbers and 2 dates. > When I test it without setting the customer it take to me 614 milliseconds > to create the 1250 instances but if I look up for each client according to > the client code it take to me 204158 milliseconds (3.40 minutes). > Customers is a MagmaCollection and this is the method of the message that > I'm sending 1250 times: > customerAtDocumentNumber: unString sex: otroString > "Devuelve un invividuo o una organizacion dependiendo de si unString > corresponde a un número de documento o a un número de cuit. NOTA: se debe > tener en cuenta el sexo por existir números de dni repetidos entre varones y > mujeres." > | aFewCustomers | > aFewCustomers := self customers where: [ :each | (each documentNumber = > unString)]. > ^customers detect: [:each | each documentNumber = unString and: [each sex = > otroString]] ifNone: [] > > > Customers has an index on documentNumber. Now I go to profile it but I need > to find how to do it in Pharo. > I thing that I can switch customers from MagmaCollection to MagmaDictionary > and set the document number + sex how the key. What do you think? So, why you don't simply add a 'customer' ivar to document and to access it, you then just need to say: document customer instead of looking it up using index? 1:1 relation is a reference. Think simple :) > See you, > Facu > -- Best regards, Igor Stasenko AKA sig. _______________________________________________ Magma mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/magma |
In reply to this post by Chris Muller-4
On Thu, Dec 9, 2010 at 10:59 PM, Chris Muller <[hidden email]> wrote: Yes, I'm not surprised that takes 3 minutes. The first problem is Yes, I don't need that look up when I navigate or use my model but in this case I'm doing a bulk load so I don't if I can avoid the look-up by a key.
The right Well to know, I'm going to try it with MagmaPreallocatedDictionary.
For now, documentNumber is a vi of customer (just aString) but it could be anObject in other iteration. Maybe is a good moment to reify it to a Document object (i need find a good name for this class) with document number and sex variables instance because I need it for the key of MagmaPreallocatedDictionary since document numbers (in Argentine) aren't unique. So, I need document number and sex to find a customer.
Thanks, Facu
_______________________________________________ Magma mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/magma |
In reply to this post by Igor Stasenko
Hi Igor,
I'm doing a bulk load form a .csv file so then I need look up for the document so it seems be the same.
The relation between aDocument (with documentNumber and sex) is 1:1 but documentNumber and customer isn't 1:1.
Facu
_______________________________________________ Magma mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/magma |
Another thing to consider, how many unique documents are there? You
could make a temporary (but persistent) standard Dictionary of Documents during the bulk-load process to provide for fast-lookup. Build up the entire Document Dictionary first, commit it, then enumerate customers to quickly associate the document(Id)'s. Something like that... On Fri, Dec 10, 2010 at 7:05 AM, Facundo Vozzi <[hidden email]> wrote: > Hi Igor, > >> >> So, why you don't simply add a 'customer' ivar to document >> and to access it, you then just need to say: >> >> document customer >> >> instead of looking it up using index? > > I'm doing a bulk load form a .csv file so then I need look up for the > document so it seems be the same. > >> >> 1:1 relation is a reference. Think simple :) > > The relation between aDocument (with documentNumber and sex) is 1:1 but > documentNumber and customer isn't 1:1. > Facu > >> >> > See you, >> > Facu >> > >> >> >> >> >> -- >> Best regards, >> Igor Stasenko AKA sig. > > Magma mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/magma |
Chirs/Igor,
I refactorized my model to use a MagmaPreallocatedDictionary with a especial unique number generated with the documentNumber and the gender of each client. Now I can proccess 1250 transactions from a csv file in less than 3 SECONDS including the time openning and proccessing of the file. So that's great, thank you.
Other thing, after the refactoring I'm getting an error when I change anything on the class structure of any class. The error is: "MaObjectSerializationSoftwareError: Individual not defined in this image".
That I did was rename two customer subclasses: Previous: Customer Individual Organization Now: Customer NaturalPerson (Persona Física)
LegalPerson (Persona Jurídica) It's strange to me because now all seem works ok and because when I rename that classes haven't persistent instances on magma repository. Do you now that I'm doing wrong? Is it possible rename a persistent class? Thanks, Facu On Fri, Dec 10, 2010 at 2:26 PM, Chris Muller <[hidden email]> wrote: Another thing to consider, how many unique documents are there? You _______________________________________________ Magma mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/magma |
On 12 December 2010 04:16, Facundo Vozzi <[hidden email]> wrote:
> Chirs/Igor, > I refactorized my model to use a MagmaPreallocatedDictionary with a especial > unique number generated with the documentNumber and the gender of each > client. > Now I can proccess 1250 transactions from a csv file in less than 3 SECONDS > including the time openning and proccessing of the file. So that's great, > thank you. Cool. > Other thing, after the refactoring I'm getting an error when I change > anything on the class structure of any class. The error is: > "MaObjectSerializationSoftwareError: Individual not defined in this image". > That I did was rename two customer subclasses: > Previous: > Customer > Individual > Organization > Now: > Customer > NaturalPerson (Persona Física) > LegalPerson (Persona Jurídica) > It's strange to me because now all seem works ok and because when I rename > that classes haven't persistent instances on magma repository. > > Do you now that I'm doing wrong? Is it possible rename a persistent class? The only person who can help you with this is Chris. Because my knowledge about Magma in this area are close to zero :) -- Best regards, Igor Stasenko AKA sig. _______________________________________________ Magma mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/magma |
Free forum by Nabble | Edit this page |