Hola kiko,
> Se pude sacar alguna conclusión de estos números??.
Cual sería la pregunta que estas tratando resolver?
Que la motiva?
Lo digo porque no entiendo porque comparás
MT con VS en velocidad, no encuentro un caso
en dónde yo dudaría de usar uno u otro.
> No parece ser tan catastrófico usar #allInstances.
No lo es.
Pero es una de las cosas que uno debe tratar de evitar,
si piensa que puede ser posible.
hasta pronto,
Ale.
----- Original Message -----
From: "kikote gregoris" <kikogregoris@...>
To: <smalltalking@...>
Sent: Tuesday, October 31, 2006 10:56 PM
Subject: [objetos] Caso de Prueba en Cambio de instancias
> Hola Gente
>
> Estuve probando el peor caso para la implementación de VS.
> Genere una colección de 1000 objetos y luego modifique su clase, luego
la recorrí enviándole un mensaje a cada objeto para obligarlos a mutar.
> Medí el tiempo que se tomo y tardo 13 segundos.
> Luego implemente una versión trucha para MT donde para mutar uso
#allInstances y realice algo parecido a lo de VS.
> Tardo 3 segundos para 1000.
>
> Se pude sacar alguna conclusión de estos números??.
> El ejemplo no incluye la generación de la colección solo la recorrida y
mutación.
> No parece ser tan catastrófico usar #allInstances.
>
> Por ultimo tengo otra pregunta.
> En VS la clase se recopila y listo, quiero decir que el St no pregunta
si quiero recompilar, solo lo hace y punto.
> En MT una clase no se recompila si uno no da la orden de que se haga, se
que es una pregunta para hacerle a quien realizo el MT pero por hay tiene
una sospecha de por que se hace esto.
>
> Saludos kiko
>
> PD: No se me ocurre una peor situación para probar en VS.
> Copio algunas de las diferencias que tiene el MT sobre otros ST.
> Aquí se destacan los beneficios de algunas de las diferencias. Si tienen
tiempo de leer algo para opinar estaría buenísimo
>
>
> Differences with other Smalltalk Dialects This section depicts the
differences that may exist with other Smalltalk dialects. In general,
Smalltalk MT tries to follow existing implementation options for the sake of
compatibility.
> Compiler options allow you to increase the compatibility at the expense
of code size and / or performance.
> Pool Dictionaries reside in the sources In Smalltalk MT, Pool
Dictionaries behave exactly like include files in C, i.e., they are part of
the source base. Other Smalltalk implementations usually design pool
dictionaries as global variables. In Smalltalk MT, a pool dictionary is not
directly accessible from the image. You edit pool dictionaries by invoking
the pool editor from the Options menu in the Class Hierarchy Browser. You
can also load include files, and save a Smalltalk pool dictionary as an
include file or as a Smalltalk chunk file.
> Benefit: Reduced runtime requirements
>
> Symbols are not instances of String In Smalltalk MT, a symbol is a byte
object whose 32 bit value is an index into the symbol table. Because of this
indirection, symbols are not unique (although their associated value is).
The benefit of this approach is that the symbol table is not required during
runtime, which substantially reduces the executable's size.
> Optionally, Smalltalk MT can be configured to use identity symbols.
> Benefit: Reduced runtime requirements
>
> Smalltalk is a class, not a dictionary In Smalltalk MT, the class
Smalltalk takes over the functionality of the Smalltalk global variable
present in most dialects. Smalltalk MT internally uses two dictionaries,
SmalltalkGlobalDictionary for global variables, and SmalltalkClassDictionary
for classes. Class Smalltalk implements also linking with an external
Smalltalk DLL.
>
> Two types of global variables: process-global and thread-local variables
Smalltalk MT introduces thread local variables variables. Once declared, a
thread-local variable exists in all threads, but its value is specific to
each thread.
> Global variables are visible from all threads.
>
> Metaclasses are created on demand A Metaclass is created on demand by
sending the message #class to a class.
> Benefit: Reduced storage requirements.
>
> Issues when adding methods to base classes In some cases, new methods
cannot be installed directly in certain base classes, such as Array,
LargeInteger, MappingTable, StringA. In these cases, the compiler saves the
source code and emits a warning that the changes will not go into effect
until the image is compressed. You must compress and restart the image to
validate the modifications.
> Note that this applies only to new methods and under certain conditions;
once installed, methods can be modified interactively.
>
> Simplified API Interface Before you can call an API, your image must be
linked with the appropriate DLL. Once this is done, you can call an API with
the keyword WINAPI.
> Because objects never move in Smalltalk MT, you can directly pass
objects as API arguments. Callbacks from non-Smalltalk code are also
painless; any block can be passed as an API argument and called by
non-Smalltalk code. Class methods can also be called, provided they belong
to one of the Export categories.
> Before an object is handed over to an API, it receives the hidden
message #asCinteger. This message asks the receiving object for its 32 bit
API representation. For example, a Window will answer the API representation
of its handle.
> Note: Smalltalk MT also supports dynamic binding, which loads a DLL when
needed at runtime. However, the programming interface is identical, which
makes it easy to switch between the two modes.
>
> Local Variables are uninitialized (optional) For performance reasons,
local variables in static contexts (method contexts without blocks) are
uninitialized (like in C compilers). Using an uninitialized local variable
generates a compilation error. However, an uninitialized state may go
undetected accurately if conditional statements are used.
> Note: You can enable and disable local variable initializations in the
language properties.
>
> String Literals in methods are merged (optional) In order to save
space, a literal string (or any other literal byte object) that occurs
several times inside a method is only stored once. A side-effect is that an
expression such as:
> 'abc' == 'abc'
> evaluates to true.
>
> Literal Strings accept escape characters Literal strings can be
specified using escape characters, introduced by '\'. The syntax is largely
C-compliant. A consequence is that ordinary backslashes must be doubled.
>
> Other Differences in the Class Hierarchy File
> Smalltalk MT has no actual File class. The functionality is taken over
by FileStream. The identifier File is aliased to FileStream in order to
support existing code.
> A FileStream does not support some of the Stream methods that work at
the byte granularity level. This would be inefficient because FileStream
does not buffer I/O. MemoryStream should be used instead, because it takes
advantage of the memory-mapped file system exposed by Win32.
>
> Dictionary Smalltalk MT uses MappingTable by default. Dictionary is
aliased to MappingTable in order to preserve existing code.
>
> Name aliasing The compiler accepts alternate identifiers for some
classes. The alternate name lookup has the least precedence, so it doesn't
interfere with existing classes. Installing a class that has an aliased name
overrides the alias.
> Example
> By default, Dictionary is an alias for MappingTable. The extra Smalltalk
project installs a class Dictionary that is defined as a Set of Associations
(and therefore compatible with the original definition of Dictionary).
Source code that references Dictionary will automatically refer to the new
class when the project is installed, and to MappingTable when the project is
removed.
>
>
> Frequently Asked Questions Table of Contents
> Deliverable Files
> Questions about source code strategy
> What is the purpose of the message #_asCinteger ?
> Is there a Notifier in Smalltalk MT?
> What is the purpose of the window property 'STOBJ'?
> ApplicationProcess allInstances is empty
> I evaluated the following: [ ^self ] fork, and it raises an exception
> Getting Started with Projects...
> Building an Executable
> Debugging an Executable
> Miscellaneous Memory Allocation Questions
> How do I stop a thread?
> How do I exit Smalltalk MT by program?
> MappedObjectStream only stores one object
> Closing a memory-mapped file while keeping a reference generates
exception
> Saving an image over the network
> Problems saving an image
> Sample Code: Loading and unloading ActiveX Controls dynamically
> Thread storage and blocks
> I cannot access Transcript from another thread
>
> ---------------------------------
>
> Deliverable Files What follows is a description of the files that you
must or may ship with a Smalltalk MT executable:
> File
> Description
> Status
> strtdll25.DLL
> runtime routines for ST/MT (15kB)
> required
> stsrl.DLL
> serialization routines (60kB)
> optional - used by memory-mapped files and object serialization
> stolestd.DLL
> OLE helper library (44kB)
> optional - used by some OLE / ActiveX classes
> Back To Top
>
> ---------------------------------
>
> Source code strategy and naming conventions Class libraries
> Smalltalk MT only implements classes / methods that are also used by
the development environment or samples. That way, all source code has been
tested.
> Underscores
> Underscores identify private messages, classes, or pseudo-messages
(inlined messages).
> Back To Top
>
> ---------------------------------
>
> What is the purpose of #_asCinteger? The message #_asCinteger is sent
implicitly to API arguments, and returns a 32 bit representation of an
object. If the object cannot be passed to an API (for example nil), it
raises an exception.
> You can bypass this message with one of the messages #basicAddress,
#_asInteger, or more generally with an inline message that returns a known
type (such as #_longAtOffset:).
> Note that the address manipulation methods (#atAddress:put: etc.) do not
send the message, so you may have to send it yourself if the parameter is
not an integer or LONG type.
> Example: MemoryManager atAddress: ppEnumConnectionPoints put: ienum
_asCinteger.
> Back To Top
>
> ---------------------------------
>
> Does Smalltalk MT have a Notifier? Each window implements its own
window procedure (although most windows inherit the default window procedure
in Window), and exports it to the operating system.
> A Smalltalk-created window other than a dialog box reserves private data
in its window creation structure, and stores the address of the Smalltalk
object in that slot (remember: in ST/MT, objects are never moved).
> A DialogBox functions exactly like a Dialog Box in C/C++ ; each instance
has its own dialog procedure that references the Smalltalk object.
> Back To Top
>
> ---------------------------------
>
> What is the purpose of the window property 'STOBJ' that is associated
with a window? The purpose of this property is to be able to retrieve the
Smalltalk object associated with a window, given the window handle. If the
window is not maintained by Smalltalk (i.e., the window procedure is
implemented elsewhere), the property will not be set.
> Back To Top
>
> ---------------------------------
>
> I evaluated the following: [ ^self ] fork, and it raises an exception
The return statement in a block returns from the method that defines the
block. If you create a thread that executes this block, the new thread would
attempt to return from a method context in a parallel thread, therefore
switching the stack and crashing. And your original thread would crash as
well because the other thread corrupted its stack. Therefore, the code that
actually returns verifies that the return is valid, and raises a software
exception if it cannot return.
> Back To Top
>
> ---------------------------------
>
> How do I stop a forked thread? A forked block exits naturally. If you
created the thread with one of the #fork messages, there is no need to worry
about exiting the thread. For example:
> [ | a | 1000 timesRepeat: [ a := a + 1 ] ] fork
> exits when it is done.
> In Win32, the only general way to kill a thread is to use
TerminateThread. This works on Smalltalk MT created threads as well, but
leaves some Win32 resources open (refer to the Win32 documentation).
> So, terminating a thread in an orderly fashion requires some programming
logic and synchronization. The Philosopher sample shows how to do this.
> Back To Top
>
> ---------------------------------
>
> Getting Started with Projects...
> A Windows Application requires at least the following components:
>
> source code in project format (.SP)
> resources (in a DLL)
> In order to open an application such as Generic, you must first install
the project file (generic.sp). The next step is to copy the resources into
your path (i.e., copy generic.dll to your image directory). You can then
open the application (look at the readme.txt file that comes with the sample
to see how to do this).
> Some projects require additional components before they can be used. The
Project Browser will take care of it automatically (linking with DLLs and
installing prerequisite projects).
> Back To Top
>
> ---------------------------------
>
> Building an Executable You must first define a method
ApplicationProcess>>winMain:with:with:with: that starts up your main window
(or whatever you want to do in the process). Define this method in a file
called winmain.sm and place the file in the project directory.
> The Project Browser checks for a winmain.sm file in the current project
directory before it enables the build EXE menu item.
> You can use the Interface Builder to generate a squeleton application.
In the Interface Builder, click on File|New... and select Resource Script.
Choose a target directory and the elements to include in the application.
> Back To Top
>
> ---------------------------------
>
> Debugging an Executable The generated executable raises an exception at
runtime:
> ------------------------------------------------------------------------
---
> An instance of "Undefined Object" does not understand the
> message "Symbol(16r1000ACA)". The message was sent
> by an instance of "TestClient"
> --------------------------------------------------------------------------
-
> If you enable all error assertions you'll see the message box of the
type "an instance of XXX did not understand Symbol(yyy), the message was
sent by an instance of ZZZ".
> In the development, evaluate
> Symbol value: 16r1000ACA
> and it displays the associated symbol string. You can also use the Dump
Viewer utility from the Transcript's toolbar.
>
> See also debugging for how to create a debugging version of a program.
> Back To Top
>
> ---------------------------------
>
> Miscellaneous Memory Allocation Questions a) #basicAddress always
returns an integer that is the object's address.
> b) once you take an object's address, you must ensure that it is still
referenced. The following is wrong:
> | lf |
> lf := LOGFONT new.
> lf lfFaceName: 'Courier',' New'.
> The reason is that 'Courier',' New' creates a new string which is stored
in a structure. The structure being a byte object, there are no more
references to the string so it will be collected. Instead, use the code
below instead:
>
> | lf szFont|
> lf := LOGFONT new.
> szFont := 'Courier',' New'.
> lf lfFaceName: szFont.
> self doSomethingWith: lf.
> ^'and now szFont gets out of scope'
> Note that the problem does not occur with literals (i.e., using 'Courier
New') because literals are not collected by the garbage collector.
> c) to be sure an object is not discarded, you can:
> · -use #registerObject / #releaseObject
> · allocate it on the external heap:
> (String heapAlloc: szFont size) replaceFrom: 1 to: szFont size with:
szFont; yourself
> and free it using heapFree.
> Back To Top
>
> ---------------------------------
>
> ApplicationProcess allInstances is empty ApplicationProcess is
instantiated with the message #heapAlloc, which places it on the external C
heap. The method #allInstances only returns instances allocated on the
Smalltalk heap. The method #allInstances also scans mapped memory regions.
> Back To Top
>
> ---------------------------------
>
> Handling Window messages To process a window message such as
WM_MOUSEMOVE, just implement a method named WM_XXX:with: (for a WM_XXX
message). Don't forget to return a value as specified by the documentation
of the message.
> If the window that receives the message is a Windows control, the method
above will not directly work because the window procedure is implemented by
the control. First, check whether the control send notification events to
its parent. In this case, install an event handler for the notification
(using #when:in:perform:). Otherwise, create a Smalltalk subclass of the
control that implements the windows message in question, and send it the
message #subclassWindow upon creation. The TwinEdit sample on the
distribution set demonstrates this.
> Implementing WM_USER messages Non-standard messages can be handled in
several ways:
> · If the window is a dialog box, simply reimplement
#wndProc:with:with:with: and test the msg parameter.
> · A FrameWindow can reimplement #preTranslateMessage: or
#defWindowProc:with:with:.
> · Finally, it is also possible to add a new message map to
WinMessagesEx. The key must be the message identifier and the value the
selector to invoke in the receiver.
> Back To Top
>
> ---------------------------------
>
> How to exit Smalltalk MT? To exit the development environment
programmatically, evaluate:
> Processor close
> or
> Processor close: aBlock
> where aBlock is evaluated after the garbage collector has been stopped.
Use the second method if you must close a memory-mapped file.
> Back To Top
>
> ---------------------------------
>
> MappedObjectStream only stores one object In Smalltalk MT, the standard
serialization methods use memory-mapping technology. MappedObjectStream
implements an easy-to use interface. An instance of MappedObjectStream maps
a set of objects into the address space of the process. The top-level object
is called the root object. There is only one root object, but it can be
arbitrary, and in particular it can be a collection.
> If you open an existing file in RW mode, you can modify any object that
resides in the file. When the file is saved, external references are
automatically appended to the end of the file. If you wish to add more
objects, you can add them to the root collection or to any other object in
the file.
> Back To Top
>
> ---------------------------------
>
> Closing a memory-mapped file while keeping a reference generates an
exception The default #close message does not nil out references. Instead,
use #unloadAndClose.
> Note: The garbage collector (GC) scans all object references. If you
close the mapped file while keeping a reference, an otherwise valid
reference will suddenly point to nowhere. The GC algorithm assumes that an
object reference is always valid. Otherwise, object traversal would be much
slower.
> Back To Top
>
> ---------------------------------
>
> Saving an Image over the network
> A Smalltalk image (development or runtime) can be started from a network
drive, with or without write permission. When the image is saved (which
requires write permission), the new image receives the file creation date of
the remote system. If the system times of the two computers differ, it is
possible that the new image files have an older timestamp than the original
files. This results in the new image files being overwritten when the image
is restarted via stmt.exe.
> Possible workarounds are:
> · Synchronize the clocks of the computers that are involved
> · After saving, delete the old files stimage.exe and sources.bin
and start stmt.exe with the /nobackup option
> Back To Top
>
> ---------------------------------
>
> Problems saving an image
> Exceptions while saving an image are generally due to application data
(either wanted or unwanted) in global, class or class instance variables. If
the data section of the image is not large enough to hold the data, an
access violation occurs while serializing. The solutions are:
> · If the data needs to be serialized with the image, augment the
size of the data section.
> · Otherwise, implement a #serializeWith: method that cleans up
the globally accessible variables.
>
> ---------------------------------
>
> Loading and unloading ActiveX Controls dynamically
> It is possible to load and unload ActiveX controls at runtime. One
benefit is that an application can delay loading an ActiveX control until it
is actually needed, which reduces the application startup time.
> The following code fragment loads an ActiveX control (the Microsoft Web
Browser Control) dynamically. The application must first create an
OleContainerWindow.
> | oleContainer if |
> oleContainer := self childAt: IDC_CONTROL1.
> (if := IClassFactory coCreateInstance: (GUID IIDFromString:
> '{8856F961-340A-11D0-A96B-00C04FD705A2}' )
> interface: IUnknown) notNil ifTrue: [
> oleContainer insertObject: if.
> oleContainer invoke: 500 with: 'C:\\index.htm'.
> ].
>
>
> To unload the control:
> oleContainer unload.
>
> Back To Top
>
> ---------------------------------
>
> Thread storage and blocks
> Q:
> I'm using the fork method to create multiple ST processes (i.e., Windows
threads). It seems that the variables declared in the fork block are not
thread-local:
>
> 1 to: 10 do: [ :i |
> [ | id |
> id := i.
> ] fork
> ]
> A: The code fails for several reasons:
> · First, the reference to i is a direct reference. So, by the
time the assignment gets executed, i can hold anything. In particular, the
method may even have exited.
> · Secondly, only one block instance gets created and id is
allocated in the home context, meaning that it is shared among threads (note
that the language compilation option <use automatic blocks> would allocate
it on the stack).
> You can define a TLS variable (Compiler addTlsSymbol:) to hold
thread-specific data. This would create a different variable in each thread,
but it still doesn't solve the problem of assigning the correct value of i.
> Solution:
> Implement a method that takes the variable i as argument:
>
> testFork: id
> [ Processor outputDebugLine: id printString] fork
> and run the loop as:
> 1 to: 10 do: [ :i | self testFork: i]
> Each method invocation creates a new block with its own copy of the
arguments and the code executes as expected.
> Back To Top
>
> ---------------------------------
>
> Transcript
> Transcript is a thread-local variable, therefore you cannot access it
from another thread. When you send a message to it from another thread
(which assumes that you retrieved the Transcript object in the main thread
and passed it through using a variable), Windows invokes the procedure in
the main thread and blocks the calling thread until the Transcript procedure
returns. There are cases where this could cause a deadlock because of OLE
synchronization.
> For printing output, a much better solution is to use Processor
outputDebugLine:[_with:]. The output goes to the debugging console, which
can be an external debugger or DBMon. The method prints the image name and
the thread id so you know which module and which thread writes the output.
> Back To Top
>
>
>
>
>
> __________________________________________________
> Correo Yahoo!
> Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
> ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar