Magma with style

Chris Muller ma.chris.m at gmail.com
Fri Dec 10 01:59:39 UTC 2010


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 <facundov79 at gmail.com> 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 <facundov79 at gmail.com> 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 <asqueaker at gmail.com>
>>> > 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 <facundov79 at gmail.com>
>>> >> 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
>>> >> > Magma at lists.squeakfoundation.org
>>> >> > http://lists.squeakfoundation.org/mailman/listinfo/magma
>>> >> >
>>> >> >
>>> >
>>> >
>>
>
>


More information about the Magma mailing list