If the returned object doesn't support remote invocation, then all of the object's fields and any objects referenced by the returned object have to be marshaled, which could also be an expensive operation. Not only does the object need to be created if it does not already exist, but the stub and skeleton objects need to be created, and they have to be made aware of each other. The costs of a remote invocation also vary depending on the latency of the underlying network. Different data types have different marshaling overhead. That is in stark contrast to local invocations, for which passing a reference to a simple object is no less expensive than passing a reference to a complex object.
Interface design is critical A poorly designed remote interface can kill a program's performance.
Unfortunately, the characteristics that make for a good interface design for local objects can prove inappropriate for remote objects. Excessive temporary object creation, as discussed in parts 1 and 2 of this series, can hamper distributed applications too, but excessive round-trips are an even bigger performance problem. If a caller wants to retrieve several related items simultaneously, make it easy to do so in one remote invocation, if possible. Watch out for returning remote objects when the caller may not need to hold a reference to the remote object. Watch out for passing complex objects to remote methods when the remote object doesn't necessarily need to have a copy of the object.