About ~= and ~~

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
27 messages Options
12
Reply | Threaded
Open this post in threaded view
|

About ~= and ~~

Clara Allende
Hi guys,

I'm wondering, why?

ProtoObject>> ~~ anObject
    "Answer whether the receiver and the argument are not the same object
    (do not have the same object pointer)."

    self == anObject
        ifTrue: [^ false]
        ifFalse: [^ true]

Instead of:
ProtoObject>> ~~ anObject
    "Answer whether the receiver and the argument are not the same object
    (do not have the same object pointer)."

    ^(self == anObject) not

And why?
Object >> ~= anObject
    "Answer whether the receiver and the argument do not represent the
    same object."

    ^self = anObject == false
      
Instead of
Object>> ~= anObject
    "Answer whether the receiver and the argument do not represent the
    same object."

    ^(self = anObject) not.

Is there any particular reason for this that I'm missing?
Thanks in advance!
--

"Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program."

Linus Torvalds


Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Levente Uzonyi-2
On Wed, 12 Oct 2011, Clara Allende wrote:

> Hi guys,
>
> I'm wondering, why?
>
> ProtoObject>> ~~ anObject
>    "Answer whether the receiver and the argument are not the same object
>    (do not have the same object pointer)."
>
>    self == anObject
>        ifTrue: [^ false]
>        ifFalse: [^ true]
>
> Instead of:
> ProtoObject>> ~~ anObject
>    "Answer whether the receiver and the argument are not the same object
>    (do not have the same object pointer)."
>
>    ^(self == anObject) not
>
> And why?
> Object >> ~= anObject
>    "Answer whether the receiver and the argument do not represent the
>    same object."
>
>    ^self = anObject == false
>
> Instead of
> Object>> ~= anObject
>    "Answer whether the receiver and the argument do not represent the
>    same object."
>
>    ^(self = anObject) not.
>
> Is there any particular reason for this that I'm missing?

Performance.


Levente

> Thanks in advance!
> --
>
> "*Most good programmers do programming not because they expect to get paid
> or get adulation by the public, but because it is fun to program.*"
>
> Linus Torvalds
>

Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Mariano Martinez Peck


On Wed, Oct 12, 2011 at 5:38 PM, Levente Uzonyi <[hidden email]> wrote:
On Wed, 12 Oct 2011, Clara Allende wrote:

Hi guys,

I'm wondering, why?

ProtoObject>> ~~ anObject
  "Answer whether the receiver and the argument are not the same object
  (do not have the same object pointer)."

  self == anObject
      ifTrue: [^ false]
      ifFalse: [^ true]


Hi Carla. I can think about two things. The first one, is the one Levente said, performance.
If you analyze the bycode of this method, you will see that it is extremely fast because:

1) #== has an special associated bytecode, that is, them VM maps such bytecode to an specific primitive and it is directly executed. It means that the method #== is really never sent.
2) ifTrue:ifFalse: is also optimized (inlined) by the compiler. Again, it method is never executed and instead the compiler replace a message send bytecode with jump ones.

Another possible reason (it may not be the case, but in another places it is), is to prevent VM interruption for check other processes. In summary, the VM checks whether it should execute another process of the queue after a method execution. As you know, some parts of the scheduling process is done at the image side. And from there we lack a way to say to the VM, "please execute this method without checking others processes". Hence, in a few yet very specific places of PRocess, Scheduler, Semaphore, etc, #== is used as a mean of executing something WITHOUT being interrupted. I can imagine that it may happen the same with #~~. So if you implement such method with a #not, you will indeed send a message, proving a possibilty to be interrupted.

Another reasons, similar to the previous one, is that sometimes #== is also used as a way to avoid executing method. So..there are some methods (I don't remember if #allInstancesDo: or #allObjectsDo:) will loop forever because the loop condition would be creating objects (remember that method execution creates objects such as MethodContext).
So...again, I think it may happen the same with #~~.

That being said, I agree that the method deserve a GOOD comment explaining the reasons of such optimization.

Cheers

 
Instead of:
ProtoObject>> ~~ anObject
  "Answer whether the receiver and the argument are not the same object
  (do not have the same object pointer)."

  ^(self == anObject) not

And why?
Object >> ~= anObject
  "Answer whether the receiver and the argument do not represent the
  same object."

  ^self = anObject == false

Instead of
Object>> ~= anObject
  "Answer whether the receiver and the argument do not represent the
  same object."

  ^(self = anObject) not.

Is there any particular reason for this that I'm missing?

Performance.


Levente

Thanks in advance!
--

"*Most good programmers do programming not because they expect to get paid
or get adulation by the public, but because it is fun to program.*"

Linus Torvalds





--
Mariano
http://marianopeck.wordpress.com

Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Clara Allende
Ok, now I get it :D Thanks a lot Mariano!

On 12 October 2011 12:49, Mariano Martinez Peck <[hidden email]> wrote:


On Wed, Oct 12, 2011 at 5:38 PM, Levente Uzonyi <[hidden email]> wrote:
On Wed, 12 Oct 2011, Clara Allende wrote:

Hi guys,

I'm wondering, why?

ProtoObject>> ~~ anObject
  "Answer whether the receiver and the argument are not the same object
  (do not have the same object pointer)."

  self == anObject
      ifTrue: [^ false]
      ifFalse: [^ true]


Hi Carla. I can think about two things. The first one, is the one Levente said, performance.
If you analyze the bycode of this method, you will see that it is extremely fast because:

1) #== has an special associated bytecode, that is, them VM maps such bytecode to an specific primitive and it is directly executed. It means that the method #== is really never sent.
2) ifTrue:ifFalse: is also optimized (inlined) by the compiler. Again, it method is never executed and instead the compiler replace a message send bytecode with jump ones.

Another possible reason (it may not be the case, but in another places it is), is to prevent VM interruption for check other processes. In summary, the VM checks whether it should execute another process of the queue after a method execution. As you know, some parts of the scheduling process is done at the image side. And from there we lack a way to say to the VM, "please execute this method without checking others processes". Hence, in a few yet very specific places of PRocess, Scheduler, Semaphore, etc, #== is used as a mean of executing something WITHOUT being interrupted. I can imagine that it may happen the same with #~~. So if you implement such method with a #not, you will indeed send a message, proving a possibilty to be interrupted.

Another reasons, similar to the previous one, is that sometimes #== is also used as a way to avoid executing method. So..there are some methods (I don't remember if #allInstancesDo: or #allObjectsDo:) will loop forever because the loop condition would be creating objects (remember that method execution creates objects such as MethodContext).
So...again, I think it may happen the same with #~~.

That being said, I agree that the method deserve a GOOD comment explaining the reasons of such optimization.

Cheers

 
Instead of:
ProtoObject>> ~~ anObject
  "Answer whether the receiver and the argument are not the same object
  (do not have the same object pointer)."

  ^(self == anObject) not

And why?
Object >> ~= anObject
  "Answer whether the receiver and the argument do not represent the
  same object."

  ^self = anObject == false

Instead of
Object>> ~= anObject
  "Answer whether the receiver and the argument do not represent the
  same object."

  ^(self = anObject) not.

Is there any particular reason for this that I'm missing?

Performance.


Levente

Thanks in advance!
--

"*Most good programmers do programming not because they expect to get paid
or get adulation by the public, but because it is fun to program.*"

Linus Torvalds





--
Mariano
http://marianopeck.wordpress.com




--

"Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program."

Linus Torvalds


Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Stéphane Ducasse
In reply to this post by Mariano Martinez Peck
Mariano please enhance the comments and publish them :)

Stef

On Oct 12, 2011, at 5:49 PM, Mariano Martinez Peck wrote:

>
>
> On Wed, Oct 12, 2011 at 5:38 PM, Levente Uzonyi <[hidden email]> wrote:
> On Wed, 12 Oct 2011, Clara Allende wrote:
>
> Hi guys,
>
> I'm wondering, why?
>
> ProtoObject>> ~~ anObject
>   "Answer whether the receiver and the argument are not the same object
>   (do not have the same object pointer)."
>
>   self == anObject
>       ifTrue: [^ false]
>       ifFalse: [^ true]
>
>
> Hi Carla. I can think about two things. The first one, is the one Levente said, performance.
> If you analyze the bycode of this method, you will see that it is extremely fast because:
>
> 1) #== has an special associated bytecode, that is, them VM maps such bytecode to an specific primitive and it is directly executed. It means that the method #== is really never sent.
> 2) ifTrue:ifFalse: is also optimized (inlined) by the compiler. Again, it method is never executed and instead the compiler replace a message send bytecode with jump ones.
>
> Another possible reason (it may not be the case, but in another places it is), is to prevent VM interruption for check other processes. In summary, the VM checks whether it should execute another process of the queue after a method execution. As you know, some parts of the scheduling process is done at the image side. And from there we lack a way to say to the VM, "please execute this method without checking others processes". Hence, in a few yet very specific places of PRocess, Scheduler, Semaphore, etc, #== is used as a mean of executing something WITHOUT being interrupted. I can imagine that it may happen the same with #~~. So if you implement such method with a #not, you will indeed send a message, proving a possibilty to be interrupted.
>
> Another reasons, similar to the previous one, is that sometimes #== is also used as a way to avoid executing method. So..there are some methods (I don't remember if #allInstancesDo: or #allObjectsDo:) will loop forever because the loop condition would be creating objects (remember that method execution creates objects such as MethodContext).
> So...again, I think it may happen the same with #~~.
>
> That being said, I agree that the method deserve a GOOD comment explaining the reasons of such optimization.
>
> Cheers
>
>  
> Instead of:
> ProtoObject>> ~~ anObject
>   "Answer whether the receiver and the argument are not the same object
>   (do not have the same object pointer)."
>
>   ^(self == anObject) not
>
> And why?
> Object >> ~= anObject
>   "Answer whether the receiver and the argument do not represent the
>   same object."
>
>   ^self = anObject == false
>
> Instead of
> Object>> ~= anObject
>   "Answer whether the receiver and the argument do not represent the
>   same object."
>
>   ^(self = anObject) not.
>
> Is there any particular reason for this that I'm missing?
>
> Performance.
>
>
> Levente
>
> Thanks in advance!
> --
>
> "*Most good programmers do programming not because they expect to get paid
> or get adulation by the public, but because it is fun to program.*"
>
> Linus Torvalds
>
>
>
>
>
> --
> Mariano
> http://marianopeck.wordpress.com
>


Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Mariano Martinez Peck


On Wed, Oct 12, 2011 at 6:02 PM, Stéphane Ducasse <[hidden email]> wrote:
Mariano please enhance the comments and publish them :)


I would like so....  but I would like that a real hacker tell me whether I am correct or not.

 
Stef

On Oct 12, 2011, at 5:49 PM, Mariano Martinez Peck wrote:

>
>
> On Wed, Oct 12, 2011 at 5:38 PM, Levente Uzonyi <[hidden email]> wrote:
> On Wed, 12 Oct 2011, Clara Allende wrote:
>
> Hi guys,
>
> I'm wondering, why?
>
> ProtoObject>> ~~ anObject
>   "Answer whether the receiver and the argument are not the same object
>   (do not have the same object pointer)."
>
>   self == anObject
>       ifTrue: [^ false]
>       ifFalse: [^ true]
>
>
> Hi Carla. I can think about two things. The first one, is the one Levente said, performance.
> If you analyze the bycode of this method, you will see that it is extremely fast because:
>
> 1) #== has an special associated bytecode, that is, them VM maps such bytecode to an specific primitive and it is directly executed. It means that the method #== is really never sent.
> 2) ifTrue:ifFalse: is also optimized (inlined) by the compiler. Again, it method is never executed and instead the compiler replace a message send bytecode with jump ones.
>
> Another possible reason (it may not be the case, but in another places it is), is to prevent VM interruption for check other processes. In summary, the VM checks whether it should execute another process of the queue after a method execution. As you know, some parts of the scheduling process is done at the image side. And from there we lack a way to say to the VM, "please execute this method without checking others processes". Hence, in a few yet very specific places of PRocess, Scheduler, Semaphore, etc, #== is used as a mean of executing something WITHOUT being interrupted. I can imagine that it may happen the same with #~~. So if you implement such method with a #not, you will indeed send a message, proving a possibilty to be interrupted.
>
> Another reasons, similar to the previous one, is that sometimes #== is also used as a way to avoid executing method. So..there are some methods (I don't remember if #allInstancesDo: or #allObjectsDo:) will loop forever because the loop condition would be creating objects (remember that method execution creates objects such as MethodContext).
> So...again, I think it may happen the same with #~~.
>
> That being said, I agree that the method deserve a GOOD comment explaining the reasons of such optimization.
>
> Cheers
>
>
> Instead of:
> ProtoObject>> ~~ anObject
>   "Answer whether the receiver and the argument are not the same object
>   (do not have the same object pointer)."
>
>   ^(self == anObject) not
>
> And why?
> Object >> ~= anObject
>   "Answer whether the receiver and the argument do not represent the
>   same object."
>
>   ^self = anObject == false
>
> Instead of
> Object>> ~= anObject
>   "Answer whether the receiver and the argument do not represent the
>   same object."
>
>   ^(self = anObject) not.
>
> Is there any particular reason for this that I'm missing?
>
> Performance.
>
>
> Levente
>
> Thanks in advance!
> --
>
> "*Most good programmers do programming not because they expect to get paid
> or get adulation by the public, but because it is fun to program.*"
>
> Linus Torvalds
>
>
>
>
>
> --
> Mariano
> http://marianopeck.wordpress.com
>





--
Mariano
http://marianopeck.wordpress.com

Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Mariano Martinez Peck
In reply to this post by Clara Allende


On Wed, Oct 12, 2011 at 6:00 PM, Clara Allende <[hidden email]> wrote:
Ok, now I get it :D Thanks a lot Mariano!


No problem :)
 

On 12 October 2011 12:49, Mariano Martinez Peck <[hidden email]> wrote:


On Wed, Oct 12, 2011 at 5:38 PM, Levente Uzonyi <[hidden email]> wrote:
On Wed, 12 Oct 2011, Clara Allende wrote:

Hi guys,

I'm wondering, why?

ProtoObject>> ~~ anObject
  "Answer whether the receiver and the argument are not the same object
  (do not have the same object pointer)."

  self == anObject
      ifTrue: [^ false]
      ifFalse: [^ true]


Hi Carla. I can think about two things. The first one, is the one Levente said, performance.
If you analyze the bycode of this method, you will see that it is extremely fast because:

1) #== has an special associated bytecode, that is, them VM maps such bytecode to an specific primitive and it is directly executed. It means that the method #== is really never sent.
2) ifTrue:ifFalse: is also optimized (inlined) by the compiler. Again, it method is never executed and instead the compiler replace a message send bytecode with jump ones.

Another possible reason (it may not be the case, but in another places it is), is to prevent VM interruption for check other processes. In summary, the VM checks whether it should execute another process of the queue after a method execution. As you know, some parts of the scheduling process is done at the image side. And from there we lack a way to say to the VM, "please execute this method without checking others processes". Hence, in a few yet very specific places of PRocess, Scheduler, Semaphore, etc, #== is used as a mean of executing something WITHOUT being interrupted. I can imagine that it may happen the same with #~~. So if you implement such method with a #not, you will indeed send a message, proving a possibilty to be interrupted.

Another reasons, similar to the previous one, is that sometimes #== is also used as a way to avoid executing method. So..there are some methods (I don't remember if #allInstancesDo: or #allObjectsDo:) will loop forever because the loop condition would be creating objects (remember that method execution creates objects such as MethodContext).
So...again, I think it may happen the same with #~~.

That being said, I agree that the method deserve a GOOD comment explaining the reasons of such optimization.

Cheers

 
Instead of:
ProtoObject>> ~~ anObject
  "Answer whether the receiver and the argument are not the same object
  (do not have the same object pointer)."

  ^(self == anObject) not

And why?
Object >> ~= anObject
  "Answer whether the receiver and the argument do not represent the
  same object."

  ^self = anObject == false

Instead of
Object>> ~= anObject
  "Answer whether the receiver and the argument do not represent the
  same object."

  ^(self = anObject) not.

Is there any particular reason for this that I'm missing?

Performance.


Levente

Thanks in advance!
--

"*Most good programmers do programming not because they expect to get paid
or get adulation by the public, but because it is fun to program.*"

Linus Torvalds





--
Mariano
http://marianopeck.wordpress.com




--

"Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program."

Linus Torvalds





--
Mariano
http://marianopeck.wordpress.com

Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Sven Van Caekenberghe
In reply to this post by Mariano Martinez Peck

On 12 Oct 2011, at 18:21, Mariano Martinez Peck wrote:

> I would like so....  but I would like that a real hacker tell me whether I am correct or not.

You most definitively are a real hacker !

Sven


Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

abergel
In reply to this post by Mariano Martinez Peck
Excellent description.
Just wondering: when the scheduling really happens? I thought that it is when you do a #yield or wait explicitely since scheduling is not preemptive.

Cheers,
Alexandre


On 12 Oct 2011, at 12:49, Mariano Martinez Peck wrote:

>
>
> On Wed, Oct 12, 2011 at 5:38 PM, Levente Uzonyi <[hidden email]> wrote:
> On Wed, 12 Oct 2011, Clara Allende wrote:
>
> Hi guys,
>
> I'm wondering, why?
>
> ProtoObject>> ~~ anObject
>   "Answer whether the receiver and the argument are not the same object
>   (do not have the same object pointer)."
>
>   self == anObject
>       ifTrue: [^ false]
>       ifFalse: [^ true]
>
>
> Hi Carla. I can think about two things. The first one, is the one Levente said, performance.
> If you analyze the bycode of this method, you will see that it is extremely fast because:
>
> 1) #== has an special associated bytecode, that is, them VM maps such bytecode to an specific primitive and it is directly executed. It means that the method #== is really never sent.
> 2) ifTrue:ifFalse: is also optimized (inlined) by the compiler. Again, it method is never executed and instead the compiler replace a message send bytecode with jump ones.
>
> Another possible reason (it may not be the case, but in another places it is), is to prevent VM interruption for check other processes. In summary, the VM checks whether it should execute another process of the queue after a method execution. As you know, some parts of the scheduling process is done at the image side. And from there we lack a way to say to the VM, "please execute this method without checking others processes". Hence, in a few yet very specific places of PRocess, Scheduler, Semaphore, etc, #== is used as a mean of executing something WITHOUT being interrupted. I can imagine that it may happen the same with #~~. So if you implement such method with a #not, you will indeed send a message, proving a possibilty to be interrupted.
>
> Another reasons, similar to the previous one, is that sometimes #== is also used as a way to avoid executing method. So..there are some methods (I don't remember if #allInstancesDo: or #allObjectsDo:) will loop forever because the loop condition would be creating objects (remember that method execution creates objects such as MethodContext).
> So...again, I think it may happen the same with #~~.
>
> That being said, I agree that the method deserve a GOOD comment explaining the reasons of such optimization.
>
> Cheers
>
>  
> Instead of:
> ProtoObject>> ~~ anObject
>   "Answer whether the receiver and the argument are not the same object
>   (do not have the same object pointer)."
>
>   ^(self == anObject) not
>
> And why?
> Object >> ~= anObject
>   "Answer whether the receiver and the argument do not represent the
>   same object."
>
>   ^self = anObject == false
>
> Instead of
> Object>> ~= anObject
>   "Answer whether the receiver and the argument do not represent the
>   same object."
>
>   ^(self = anObject) not.
>
> Is there any particular reason for this that I'm missing?
>
> Performance.
>
>
> Levente
>
> Thanks in advance!
> --
>
> "*Most good programmers do programming not because they expect to get paid
> or get adulation by the public, but because it is fun to program.*"
>
> Linus Torvalds
>
>
>
>
>
> --
> Mariano
> http://marianopeck.wordpress.com
>

--
_,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
Alexandre Bergel  http://www.bergel.eu
^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.






Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Stéphane Ducasse
Alex

the vm should check condition from time to time and the place where it can check is at every message send.
Since == is not a message send, when you write code with == or not even if it is semantically equivalent
its execution may be different (it looks hackish).

Stef

On Oct 12, 2011, at 6:29 PM, Alexandre Bergel wrote:

> Excellent description.
> Just wondering: when the scheduling really happens? I thought that it is when you do a #yield or wait explicitely since scheduling is not preemptive.
>
> Cheers,
> Alexandre
>
>
> On 12 Oct 2011, at 12:49, Mariano Martinez Peck wrote:
>
>>
>>
>> On Wed, Oct 12, 2011 at 5:38 PM, Levente Uzonyi <[hidden email]> wrote:
>> On Wed, 12 Oct 2011, Clara Allende wrote:
>>
>> Hi guys,
>>
>> I'm wondering, why?
>>
>> ProtoObject>> ~~ anObject
>>  "Answer whether the receiver and the argument are not the same object
>>  (do not have the same object pointer)."
>>
>>  self == anObject
>>      ifTrue: [^ false]
>>      ifFalse: [^ true]
>>
>>
>> Hi Carla. I can think about two things. The first one, is the one Levente said, performance.
>> If you analyze the bycode of this method, you will see that it is extremely fast because:
>>
>> 1) #== has an special associated bytecode, that is, them VM maps such bytecode to an specific primitive and it is directly executed. It means that the method #== is really never sent.
>> 2) ifTrue:ifFalse: is also optimized (inlined) by the compiler. Again, it method is never executed and instead the compiler replace a message send bytecode with jump ones.
>>
>> Another possible reason (it may not be the case, but in another places it is), is to prevent VM interruption for check other processes. In summary, the VM checks whether it should execute another process of the queue after a method execution. As you know, some parts of the scheduling process is done at the image side. And from there we lack a way to say to the VM, "please execute this method without checking others processes". Hence, in a few yet very specific places of PRocess, Scheduler, Semaphore, etc, #== is used as a mean of executing something WITHOUT being interrupted. I can imagine that it may happen the same with #~~. So if you implement such method with a #not, you will indeed send a message, proving a possibilty to be interrupted.
>>
>> Another reasons, similar to the previous one, is that sometimes #== is also used as a way to avoid executing method. So..there are some methods (I don't remember if #allInstancesDo: or #allObjectsDo:) will loop forever because the loop condition would be creating objects (remember that method execution creates objects such as MethodContext).
>> So...again, I think it may happen the same with #~~.
>>
>> That being said, I agree that the method deserve a GOOD comment explaining the reasons of such optimization.
>>
>> Cheers
>>
>>
>> Instead of:
>> ProtoObject>> ~~ anObject
>>  "Answer whether the receiver and the argument are not the same object
>>  (do not have the same object pointer)."
>>
>>  ^(self == anObject) not
>>
>> And why?
>> Object >> ~= anObject
>>  "Answer whether the receiver and the argument do not represent the
>>  same object."
>>
>>  ^self = anObject == false
>>
>> Instead of
>> Object>> ~= anObject
>>  "Answer whether the receiver and the argument do not represent the
>>  same object."
>>
>>  ^(self = anObject) not.
>>
>> Is there any particular reason for this that I'm missing?
>>
>> Performance.
>>
>>
>> Levente
>>
>> Thanks in advance!
>> --
>>
>> "*Most good programmers do programming not because they expect to get paid
>> or get adulation by the public, but because it is fun to program.*"
>>
>> Linus Torvalds
>>
>>
>>
>>
>>
>> --
>> Mariano
>> http://marianopeck.wordpress.com
>>
>
> --
> _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
> Alexandre Bergel  http://www.bergel.eu
> ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
>
>
>
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Eliot Miranda-2
In reply to this post by Levente Uzonyi-2


On Wed, Oct 12, 2011 at 8:38 AM, Levente Uzonyi <[hidden email]> wrote:
On Wed, 12 Oct 2011, Clara Allende wrote:

Hi guys,

I'm wondering, why?

ProtoObject>> ~~ anObject
  "Answer whether the receiver and the argument are not the same object
  (do not have the same object pointer)."

  self == anObject
      ifTrue: [^ false]
      ifFalse: [^ true]

Instead of:
ProtoObject>> ~~ anObject
  "Answer whether the receiver and the argument are not the same object
  (do not have the same object pointer)."

  ^(self == anObject) not

And why?
Object >> ~= anObject
  "Answer whether the receiver and the argument do not represent the
  same object."

  ^self = anObject == false

Instead of
Object>> ~= anObject
  "Answer whether the receiver and the argument do not represent the
  same object."

  ^(self = anObject) not.

Is there any particular reason for this that I'm missing?

Performance.

But better still is to add a ~~ primitive.  I did this for VisualWorks.  e.g. primitive 150 is free.  why don't we use that for 1.4/4.3?
 


Levente

Thanks in advance!
--

"*Most good programmers do programming not because they expect to get paid
or get adulation by the public, but because it is fun to program.*"

Linus Torvalds





--
best,
Eliot

Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

abergel
In reply to this post by Stéphane Ducasse
Ok, scheduling in Pharo may happen when sending a message.

Thanks for the clarification.

Cheers,
Alexandre


On 12 Oct 2011, at 13:40, Stéphane Ducasse wrote:

> Alex
>
> the vm should check condition from time to time and the place where it can check is at every message send.
> Since == is not a message send, when you write code with == or not even if it is semantically equivalent
> its execution may be different (it looks hackish).
>
> Stef
>
> On Oct 12, 2011, at 6:29 PM, Alexandre Bergel wrote:
>
>> Excellent description.
>> Just wondering: when the scheduling really happens? I thought that it is when you do a #yield or wait explicitely since scheduling is not preemptive.
>>
>> Cheers,
>> Alexandre
>>
>>
>> On 12 Oct 2011, at 12:49, Mariano Martinez Peck wrote:
>>
>>>
>>>
>>> On Wed, Oct 12, 2011 at 5:38 PM, Levente Uzonyi <[hidden email]> wrote:
>>> On Wed, 12 Oct 2011, Clara Allende wrote:
>>>
>>> Hi guys,
>>>
>>> I'm wondering, why?
>>>
>>> ProtoObject>> ~~ anObject
>>> "Answer whether the receiver and the argument are not the same object
>>> (do not have the same object pointer)."
>>>
>>> self == anObject
>>>     ifTrue: [^ false]
>>>     ifFalse: [^ true]
>>>
>>>
>>> Hi Carla. I can think about two things. The first one, is the one Levente said, performance.
>>> If you analyze the bycode of this method, you will see that it is extremely fast because:
>>>
>>> 1) #== has an special associated bytecode, that is, them VM maps such bytecode to an specific primitive and it is directly executed. It means that the method #== is really never sent.
>>> 2) ifTrue:ifFalse: is also optimized (inlined) by the compiler. Again, it method is never executed and instead the compiler replace a message send bytecode with jump ones.
>>>
>>> Another possible reason (it may not be the case, but in another places it is), is to prevent VM interruption for check other processes. In summary, the VM checks whether it should execute another process of the queue after a method execution. As you know, some parts of the scheduling process is done at the image side. And from there we lack a way to say to the VM, "please execute this method without checking others processes". Hence, in a few yet very specific places of PRocess, Scheduler, Semaphore, etc, #== is used as a mean of executing something WITHOUT being interrupted. I can imagine that it may happen the same with #~~. So if you implement such method with a #not, you will indeed send a message, proving a possibilty to be interrupted.
>>>
>>> Another reasons, similar to the previous one, is that sometimes #== is also used as a way to avoid executing method. So..there are some methods (I don't remember if #allInstancesDo: or #allObjectsDo:) will loop forever because the loop condition would be creating objects (remember that method execution creates objects such as MethodContext).
>>> So...again, I think it may happen the same with #~~.
>>>
>>> That being said, I agree that the method deserve a GOOD comment explaining the reasons of such optimization.
>>>
>>> Cheers
>>>
>>>
>>> Instead of:
>>> ProtoObject>> ~~ anObject
>>> "Answer whether the receiver and the argument are not the same object
>>> (do not have the same object pointer)."
>>>
>>> ^(self == anObject) not
>>>
>>> And why?
>>> Object >> ~= anObject
>>> "Answer whether the receiver and the argument do not represent the
>>> same object."
>>>
>>> ^self = anObject == false
>>>
>>> Instead of
>>> Object>> ~= anObject
>>> "Answer whether the receiver and the argument do not represent the
>>> same object."
>>>
>>> ^(self = anObject) not.
>>>
>>> Is there any particular reason for this that I'm missing?
>>>
>>> Performance.
>>>
>>>
>>> Levente
>>>
>>> Thanks in advance!
>>> --
>>>
>>> "*Most good programmers do programming not because they expect to get paid
>>> or get adulation by the public, but because it is fun to program.*"
>>>
>>> Linus Torvalds
>>>
>>>
>>>
>>>
>>>
>>> --
>>> Mariano
>>> http://marianopeck.wordpress.com
>>>
>>
>> --
>> _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
>> Alexandre Bergel  http://www.bergel.eu
>> ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
>>
>>
>>
>>
>>
>>
>
>

--
_,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
Alexandre Bergel  http://www.bergel.eu
^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.






Reply | Threaded
Open this post in threaded view
|

Re: [Vm-dev] Re: About ~= and ~~

Mariano Martinez Peck
In reply to this post by Eliot Miranda-2


On Wed, Oct 12, 2011 at 6:44 PM, Eliot Miranda <[hidden email]> wrote:
 


On Wed, Oct 12, 2011 at 8:38 AM, Levente Uzonyi <[hidden email]> wrote:
On Wed, 12 Oct 2011, Clara Allende wrote:

Hi guys,

I'm wondering, why?

ProtoObject>> ~~ anObject
  "Answer whether the receiver and the argument are not the same object
  (do not have the same object pointer)."

  self == anObject
      ifTrue: [^ false]
      ifFalse: [^ true]

Instead of:
ProtoObject>> ~~ anObject
  "Answer whether the receiver and the argument are not the same object
  (do not have the same object pointer)."

  ^(self == anObject) not

And why?
Object >> ~= anObject
  "Answer whether the receiver and the argument do not represent the
  same object."

  ^self = anObject == false

Instead of
Object>> ~= anObject
  "Answer whether the receiver and the argument do not represent the
  same object."

  ^(self = anObject) not.

Is there any particular reason for this that I'm missing?

Performance.

But better still is to add a ~~ primitive.  I did this for VisualWorks.  e.g. primitive 150 is free.  why don't we use that for 1.4/4.3?
 

with or without special bytecode associated?

 


Levente

Thanks in advance!
--

"*Most good programmers do programming not because they expect to get paid
or get adulation by the public, but because it is fun to program.*"

Linus Torvalds





--
best,
Eliot





--
Mariano
http://marianopeck.wordpress.com

Reply | Threaded
Open this post in threaded view
|

Re: [Vm-dev] Re: About ~= and ~~

Eliot Miranda-2


On Wed, Oct 12, 2011 at 10:26 AM, Mariano Martinez Peck <[hidden email]> wrote:
 


On Wed, Oct 12, 2011 at 6:44 PM, Eliot Miranda <[hidden email]> wrote:
 


On Wed, Oct 12, 2011 at 8:38 AM, Levente Uzonyi <[hidden email]> wrote:
On Wed, 12 Oct 2011, Clara Allende wrote:

Hi guys,

I'm wondering, why?

ProtoObject>> ~~ anObject
  "Answer whether the receiver and the argument are not the same object
  (do not have the same object pointer)."

  self == anObject
      ifTrue: [^ false]
      ifFalse: [^ true]

Instead of:
ProtoObject>> ~~ anObject
  "Answer whether the receiver and the argument are not the same object
  (do not have the same object pointer)."

  ^(self == anObject) not

And why?
Object >> ~= anObject
  "Answer whether the receiver and the argument do not represent the
  same object."

  ^self = anObject == false

Instead of
Object>> ~= anObject
  "Answer whether the receiver and the argument do not represent the
  same object."

  ^(self = anObject) not.

Is there any particular reason for this that I'm missing?

Performance.

But better still is to add a ~~ primitive.  I did this for VisualWorks.  e.g. primitive 150 is free.  why don't we use that for 1.4/4.3?
 

with or without special bytecode associated?

Initially without.  Dynamic frequency is low, and primitive adds significant performance over the non-primitive version.  One could use the blockCopy: special bytecode but I'd wait until doing a complete bytecode set redesign.
 

 


Levente

Thanks in advance!
--

"*Most good programmers do programming not because they expect to get paid
or get adulation by the public, but because it is fun to program.*"

Linus Torvalds





--
best,
Eliot





--
Mariano
http://marianopeck.wordpress.com





--
best,
Eliot

Reply | Threaded
Open this post in threaded view
|

Re: [Vm-dev] Re: About ~= and ~~

Mariano Martinez Peck


On Wed, Oct 12, 2011 at 7:29 PM, Eliot Miranda <[hidden email]> wrote:
 


On Wed, Oct 12, 2011 at 10:26 AM, Mariano Martinez Peck <[hidden email]> wrote:
 


On Wed, Oct 12, 2011 at 6:44 PM, Eliot Miranda <[hidden email]> wrote:
 


On Wed, Oct 12, 2011 at 8:38 AM, Levente Uzonyi <[hidden email]> wrote:
On Wed, 12 Oct 2011, Clara Allende wrote:

Hi guys,

I'm wondering, why?

ProtoObject>> ~~ anObject
  "Answer whether the receiver and the argument are not the same object
  (do not have the same object pointer)."

  self == anObject
      ifTrue: [^ false]
      ifFalse: [^ true]

Instead of:
ProtoObject>> ~~ anObject
  "Answer whether the receiver and the argument are not the same object
  (do not have the same object pointer)."

  ^(self == anObject) not

And why?
Object >> ~= anObject
  "Answer whether the receiver and the argument do not represent the
  same object."

  ^self = anObject == false

Instead of
Object>> ~= anObject
  "Answer whether the receiver and the argument do not represent the
  same object."

  ^(self = anObject) not.

Is there any particular reason for this that I'm missing?

Performance.

But better still is to add a ~~ primitive.  I did this for VisualWorks.  e.g. primitive 150 is free.  why don't we use that for 1.4/4.3?
 

with or without special bytecode associated?

Initially without.  

+1
 
Dynamic frequency is low, and primitive adds significant performance over the non-primitive version.  One could use the blockCopy: special bytecode but I'd wait until doing a complete bytecode set redesign.
 

 


Levente

Thanks in advance!
--

"*Most good programmers do programming not because they expect to get paid
or get adulation by the public, but because it is fun to program.*"

Linus Torvalds





--
best,
Eliot





--
Mariano
http://marianopeck.wordpress.com





--
best,
Eliot





--
Mariano
http://marianopeck.wordpress.com

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: [Vm-dev] Re: About ~= and ~~

Eliot Miranda-2
OK, in the end I decided on primitive number 169. It doesn't waste the 150-159 range and is in amongst primitiveAdoptInstance and primitiveSetIdentityHash.  David, would you like to integrate this into the main branch?

On Wed, Oct 12, 2011 at 10:47 AM, Mariano Martinez Peck <[hidden email]> wrote:


On Wed, Oct 12, 2011 at 7:29 PM, Eliot Miranda <[hidden email]> wrote:
 


On Wed, Oct 12, 2011 at 10:26 AM, Mariano Martinez Peck <[hidden email]> wrote:
 


On Wed, Oct 12, 2011 at 6:44 PM, Eliot Miranda <[hidden email]> wrote:
 


On Wed, Oct 12, 2011 at 8:38 AM, Levente Uzonyi <[hidden email]> wrote:
On Wed, 12 Oct 2011, Clara Allende wrote:

Hi guys,

I'm wondering, why?

ProtoObject>> ~~ anObject
  "Answer whether the receiver and the argument are not the same object
  (do not have the same object pointer)."

  self == anObject
      ifTrue: [^ false]
      ifFalse: [^ true]

Instead of:
ProtoObject>> ~~ anObject
  "Answer whether the receiver and the argument are not the same object
  (do not have the same object pointer)."

  ^(self == anObject) not

And why?
Object >> ~= anObject
  "Answer whether the receiver and the argument do not represent the
  same object."

  ^self = anObject == false

Instead of
Object>> ~= anObject
  "Answer whether the receiver and the argument do not represent the
  same object."

  ^(self = anObject) not.

Is there any particular reason for this that I'm missing?

Performance.

But better still is to add a ~~ primitive.  I did this for VisualWorks.  e.g. primitive 150 is free.  why don't we use that for 1.4/4.3?
 

with or without special bytecode associated?

Initially without.  

+1
 
Dynamic frequency is low, and primitive adds significant performance over the non-primitive version.  One could use the blockCopy: special bytecode but I'd wait until doing a complete bytecode set redesign.
 

 


Levente

Thanks in advance!
--

"*Most good programmers do programming not because they expect to get paid
or get adulation by the public, but because it is fun to program.*"

Linus Torvalds





--
best,
Eliot





--
Mariano
http://marianopeck.wordpress.com





--
best,
Eliot





--
Mariano
http://marianopeck.wordpress.com







--
best,
Eliot


primitiveNotIdentical.st (43K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Levente Uzonyi-2
In reply to this post by Mariano Martinez Peck
On Wed, 12 Oct 2011, Mariano Martinez Peck wrote:

> On Wed, Oct 12, 2011 at 5:38 PM, Levente Uzonyi <[hidden email]> wrote:
>
>> On Wed, 12 Oct 2011, Clara Allende wrote:
>>
>>  Hi guys,
>>>
>>> I'm wondering, why?
>>>
>>> ProtoObject>> ~~ anObject
>>>   "Answer whether the receiver and the argument are not the same object
>>>   (do not have the same object pointer)."
>>>
>>>   self == anObject
>>>       ifTrue: [^ false]
>>>       ifFalse: [^ true]
>>>
>>>
> Hi Carla. I can think about two things. The first one, is the one Levente
> said, performance.
> If you analyze the bycode of this method, you will see that it is extremely
> fast because:
>
> 1) #== has an special associated bytecode, that is, them VM maps such
> bytecode to an specific primitive and it is directly executed. It means that
> the method #== is really never sent.
> 2) ifTrue:ifFalse: is also optimized (inlined) by the compiler. Again, it
> method is never executed and instead the compiler replace a message send
> bytecode with jump ones.
>
> Another possible reason (it may not be the case, but in another places it
> is), is to prevent VM interruption for check other processes. In summary,
> the VM checks whether it should execute another process of the queue after a
> method execution. As you know, some parts of the scheduling process is done
> at the image side. And from there we lack a way to say to the VM, "please
> execute this method without checking others processes". Hence, in a few yet
> very specific places of PRocess, Scheduler, Semaphore, etc, #== is used as a
> mean of executing something WITHOUT being interrupted. I can imagine that it
> may happen the same with #~~. So if you implement such method with a #not,
> you will indeed send a message, proving a possibilty to be interrupted.

I don't see how this would be a reason. When you send #~~, then you
explicitly allow a suspension point, so not using #not won't avoid
suspension points.

>
> Another reasons, similar to the previous one, is that sometimes #== is also
> used as a way to avoid executing method. So..there are some methods (I don't
> remember if #allInstancesDo: or #allObjectsDo:) will loop forever because

#allInstancesDo: uses primitives to avoid the problem. #allObjectsDo: uses
a custom marker object, so creating new objects won't cause infinite loop
(because gc doesn't change the order of any two objects).

> the loop condition would be creating objects (remember that method execution
> creates objects such as MethodContext).

Contexts object are not created until requested and these loops don't
need contexts. Some old methods interating through all/some objects use 0
as the marker object. These may have problems with objects created during
their loops.


Levente

> So...again, I think it may happen the same with #~~.
>
> That being said, I agree that the method deserve a GOOD comment explaining
> the reasons of such optimization.
>
> Cheers
>
>
>
>> Instead of:
>>> ProtoObject>> ~~ anObject
>>>   "Answer whether the receiver and the argument are not the same object
>>>   (do not have the same object pointer)."
>>>
>>>   ^(self == anObject) not
>>>
>>> And why?
>>> Object >> ~= anObject
>>>   "Answer whether the receiver and the argument do not represent the
>>>   same object."
>>>
>>>   ^self = anObject == false
>>>
>>> Instead of
>>> Object>> ~= anObject
>>>   "Answer whether the receiver and the argument do not represent the
>>>   same object."
>>>
>>>   ^(self = anObject) not.
>>>
>>> Is there any particular reason for this that I'm missing?
>>>
>>
>> Performance.
>>
>>
>> Levente
>>
>>  Thanks in advance!
>>> --
>>>
>>> "*Most good programmers do programming not because they expect to get paid
>>> or get adulation by the public, but because it is fun to program.*"
>>>
>>> Linus Torvalds
>>>
>>>
>>
>
>
> --
> Mariano
> http://marianopeck.wordpress.com
>

Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Igor Stasenko
On 12 October 2011 23:22, Levente Uzonyi <[hidden email]> wrote:

> On Wed, 12 Oct 2011, Mariano Martinez Peck wrote:
>
>> On Wed, Oct 12, 2011 at 5:38 PM, Levente Uzonyi <[hidden email]> wrote:
>>
>>> On Wed, 12 Oct 2011, Clara Allende wrote:
>>>
>>>  Hi guys,
>>>>
>>>> I'm wondering, why?
>>>>
>>>> ProtoObject>> ~~ anObject
>>>>  "Answer whether the receiver and the argument are not the same object
>>>>  (do not have the same object pointer)."
>>>>
>>>>  self == anObject
>>>>      ifTrue: [^ false]
>>>>      ifFalse: [^ true]
>>>>
>>>>
>> Hi Carla. I can think about two things. The first one, is the one Levente
>> said, performance.
>> If you analyze the bycode of this method, you will see that it is
>> extremely
>> fast because:
>>
>> 1) #== has an special associated bytecode, that is, them VM maps such
>> bytecode to an specific primitive and it is directly executed. It means
>> that
>> the method #== is really never sent.
>> 2) ifTrue:ifFalse: is also optimized (inlined) by the compiler. Again, it
>> method is never executed and instead the compiler replace a message send
>> bytecode with jump ones.
>>
>> Another possible reason (it may not be the case, but in another places it
>> is), is to prevent VM interruption for check other processes. In summary,
>> the VM checks whether it should execute another process of the queue after
>> a
>> method execution. As you know, some parts of the scheduling process is
>> done
>> at the image side. And from there we lack a way to say to the VM, "please
>> execute this method without checking others processes". Hence, in a few
>> yet
>> very specific places of PRocess, Scheduler, Semaphore, etc, #== is used as
>> a
>> mean of executing something WITHOUT being interrupted. I can imagine that
>> it
>> may happen the same with #~~. So if you implement such method with a #not,
>> you will indeed send a message, proving a possibilty to be interrupted.
>
> I don't see how this would be a reason. When you send #~~, then you
> explicitly allow a suspension point, so not using #not won't avoid
> suspension points.
>

To my thinking, in a first place, i would ask:
why instead of fixing the code which may be affected by having or not
suspension points,
we introducing new workarounds ??

I think it is bad excuse for introduction of new primitive.
If we miss some atomicity for semaphores, lets add a primitive(s)
which fixing the semaphore issue(s).
But introducing new primitive to avoid suspension?!?!  i cannot follow
this line of thinking.

>>
>> Another reasons, similar to the previous one, is that sometimes #== is
>> also
>> used as a way to avoid executing method. So..there are some methods (I
>> don't
>> remember if #allInstancesDo: or #allObjectsDo:) will loop forever because
>
> #allInstancesDo: uses primitives to avoid the problem. #allObjectsDo: uses a
> custom marker object, so creating new objects won't cause infinite loop
> (because gc doesn't change the order of any two objects).
>
>> the loop condition would be creating objects (remember that method
>> execution
>> creates objects such as MethodContext).
>
> Contexts object are not created until requested and these loops don't need
> contexts. Some old methods interating through all/some objects use 0 as the
> marker object. These may have problems with objects created during their
> loops.
>
>
> Levente
>



--
Best regards,
Igor Stasenko.

Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Levente Uzonyi-2
On Thu, 13 Oct 2011, Igor Stasenko wrote:

> On 12 October 2011 23:22, Levente Uzonyi <[hidden email]> wrote:
>> On Wed, 12 Oct 2011, Mariano Martinez Peck wrote:
>>
>>> On Wed, Oct 12, 2011 at 5:38 PM, Levente Uzonyi <[hidden email]> wrote:
>>>
>>>> On Wed, 12 Oct 2011, Clara Allende wrote:
>>>>
>>>>  Hi guys,
>>>>>
>>>>> I'm wondering, why?
>>>>>
>>>>> ProtoObject>> ~~ anObject
>>>>>  "Answer whether the receiver and the argument are not the same object
>>>>>  (do not have the same object pointer)."
>>>>>
>>>>>  self == anObject
>>>>>      ifTrue: [^ false]
>>>>>      ifFalse: [^ true]
>>>>>
>>>>>
>>> Hi Carla. I can think about two things. The first one, is the one Levente
>>> said, performance.
>>> If you analyze the bycode of this method, you will see that it is
>>> extremely
>>> fast because:
>>>
>>> 1) #== has an special associated bytecode, that is, them VM maps such
>>> bytecode to an specific primitive and it is directly executed. It means
>>> that
>>> the method #== is really never sent.
>>> 2) ifTrue:ifFalse: is also optimized (inlined) by the compiler. Again, it
>>> method is never executed and instead the compiler replace a message send
>>> bytecode with jump ones.
>>>
>>> Another possible reason (it may not be the case, but in another places it
>>> is), is to prevent VM interruption for check other processes. In summary,
>>> the VM checks whether it should execute another process of the queue after
>>> a
>>> method execution. As you know, some parts of the scheduling process is
>>> done
>>> at the image side. And from there we lack a way to say to the VM, "please
>>> execute this method without checking others processes". Hence, in a few
>>> yet
>>> very specific places of PRocess, Scheduler, Semaphore, etc, #== is used as
>>> a
>>> mean of executing something WITHOUT being interrupted. I can imagine that
>>> it
>>> may happen the same with #~~. So if you implement such method with a #not,
>>> you will indeed send a message, proving a possibilty to be interrupted.
>>
>> I don't see how this would be a reason. When you send #~~, then you
>> explicitly allow a suspension point, so not using #not won't avoid
>> suspension points.
>>
>
> To my thinking, in a first place, i would ask:
> why instead of fixing the code which may be affected by having or not
> suspension points,
> we introducing new workarounds ??
Which code needs to be fixed?

>
> I think it is bad excuse for introduction of new primitive.
> If we miss some atomicity for semaphores, lets add a primitive(s)
> which fixing the semaphore issue(s).

Are there any issues with semaphores?

> But introducing new primitive to avoid suspension?!?!  i cannot follow
> this line of thinking.

I guess you're not replying to my mail, but Eliot's. Btw there's no such
"line of thinking". He didn't add the primitive for #~~ to avoid a
suspension point, but to improve it's performance.


Levente

>
>>>
>>> Another reasons, similar to the previous one, is that sometimes #== is
>>> also
>>> used as a way to avoid executing method. So..there are some methods (I
>>> don't
>>> remember if #allInstancesDo: or #allObjectsDo:) will loop forever because
>>
>> #allInstancesDo: uses primitives to avoid the problem. #allObjectsDo: uses a
>> custom marker object, so creating new objects won't cause infinite loop
>> (because gc doesn't change the order of any two objects).
>>
>>> the loop condition would be creating objects (remember that method
>>> execution
>>> creates objects such as MethodContext).
>>
>> Contexts object are not created until requested and these loops don't need
>> contexts. Some old methods interating through all/some objects use 0 as the
>> marker object. These may have problems with objects created during their
>> loops.
>>
>>
>> Levente
>>
>
>
>
> --
> Best regards,
> Igor Stasenko.
>
>
Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Eliot Miranda-2


2011/10/12 Levente Uzonyi <[hidden email]>
On Thu, 13 Oct 2011, Igor Stasenko wrote:

On 12 October 2011 23:22, Levente Uzonyi <[hidden email]> wrote:
On Wed, 12 Oct 2011, Mariano Martinez Peck wrote:

On Wed, Oct 12, 2011 at 5:38 PM, Levente Uzonyi <[hidden email]> wrote:

On Wed, 12 Oct 2011, Clara Allende wrote:

 Hi guys,

I'm wondering, why?

ProtoObject>> ~~ anObject
 "Answer whether the receiver and the argument are not the same object
 (do not have the same object pointer)."

 self == anObject
     ifTrue: [^ false]
     ifFalse: [^ true]


Hi Carla. I can think about two things. The first one, is the one Levente
said, performance.
If you analyze the bycode of this method, you will see that it is
extremely
fast because:

1) #== has an special associated bytecode, that is, them VM maps such
bytecode to an specific primitive and it is directly executed. It means
that
the method #== is really never sent.
2) ifTrue:ifFalse: is also optimized (inlined) by the compiler. Again, it
method is never executed and instead the compiler replace a message send
bytecode with jump ones.

Another possible reason (it may not be the case, but in another places it
is), is to prevent VM interruption for check other processes. In summary,
the VM checks whether it should execute another process of the queue after
a
method execution. As you know, some parts of the scheduling process is
done
at the image side. And from there we lack a way to say to the VM, "please
execute this method without checking others processes". Hence, in a few
yet
very specific places of PRocess, Scheduler, Semaphore, etc, #== is used as
a
mean of executing something WITHOUT being interrupted. I can imagine that
it
may happen the same with #~~. So if you implement such method with a #not,
you will indeed send a message, proving a possibilty to be interrupted.

I don't see how this would be a reason. When you send #~~, then you
explicitly allow a suspension point, so not using #not won't avoid
suspension points.


To my thinking, in a first place, i would ask:
why instead of fixing the code which may be affected by having or not
suspension points,
we introducing new workarounds ??

Which code needs to be fixed?



I think it is bad excuse for introduction of new primitive.
If we miss some atomicity for semaphores, lets add a primitive(s)
which fixing the semaphore issue(s).

Are there any issues with semaphores?


But introducing new primitive to avoid suspension?!?!  i cannot follow
this line of thinking.

I guess you're not replying to my mail, but Eliot's. Btw there's no such "line of thinking". He didn't add the primitive for #~~ to avoid a suspension point, but to improve it's performance.

+1.  The primitive is nearly twice as fast as the old method in my measurements, which are these:

| null |
null := Time millisecondsToRun: [1 to: 1000000000 do: [:i| i - i]]. "- is an inlined"
(Time millisecondsToRun: [1 to: 1000000000 do: [:i| i ~~ i]]) - null

 I got about 1200 ms before the primitive, about 660 afterwards, but there's noise to contend with.  Anyway, significantly faster.



Levente




Another reasons, similar to the previous one, is that sometimes #== is
also
used as a way to avoid executing method. So..there are some methods (I
don't
remember if #allInstancesDo: or #allObjectsDo:) will loop forever because

#allInstancesDo: uses primitives to avoid the problem. #allObjectsDo: uses a
custom marker object, so creating new objects won't cause infinite loop
(because gc doesn't change the order of any two objects).

the loop condition would be creating objects (remember that method
execution
creates objects such as MethodContext).

Contexts object are not created until requested and these loops don't need
contexts. Some old methods interating through all/some objects use 0 as the
marker object. These may have problems with objects created during their
loops.


Levente




--
Best regards,
Igor Stasenko.




--
best,
Eliot

12