Konst_One, ответь за базар!

Разговоры на любые темы: вы можете обсудить здесь какой-либо сайт, найти единомышленников или просто пообщаться...
tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Konst_One, ответь за базар!

Сообщение tyomitch » 30.04.2005 (Сб) 10:22

Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 30.04.2005 (Сб) 11:37

Да, мне тоже интересно.

Несколько раз видел у Эпплмана, что передача по ссылке в VB эффективнее, и тоже не понимаю почему (кроме строк).
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Ruslan Demidow
Мужчина!
Мужчина!
Аватара пользователя
 
Сообщения: 987
Зарегистрирован: 25.03.2004 (Чт) 13:39
Откуда: N.Novgorod

Сообщение Ruslan Demidow » 30.04.2005 (Сб) 12:08

Может быть открою Америку, а может быть и покажу своё незнание - но я читал, что если объекты передавать в процедуру по значению, а не по ссылке, то при этом создаётся локальная копия объекта (что отнимает некоторые ресурсы). А если по ссылке, то никакого копирования объекта не происходит и соответственно процедура получает адрес объекта в памяти и работает напрямую с объектом. Может быть Const_One это имел ввиду?
Мне просто самому интересна обоснованность позиций обеих сторон.
Это Ж-ж-ж-ж неспроста (с) Винни-Пух

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 30.04.2005 (Сб) 12:12

Передача по значению сопровождается копированием объекта лишь в том случае, когда объект структурного типа. Когда объект ссылочного типа, передача по значению означает копирование не объекта, а ссылки на него.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Ruslan Demidow
Мужчина!
Мужчина!
Аватара пользователя
 
Сообщения: 987
Зарегистрирован: 25.03.2004 (Чт) 13:39
Откуда: N.Novgorod

Сообщение Ruslan Demidow » 30.04.2005 (Сб) 12:16

GSerg писал(а):Передача по значению сопровождается копированием объекта лишь в том случае, когда объект структурного типа. Когда объект ссылочного типа, передача по значению означает копирование не объекта, а ссылки на него.

Спасибо за разъяснение GSerg, это уточнение для меня не лишнее и в дальнейшем пригодится. :) У меня больше вопросов нет.... Хотя нет - есть. Так тогда получается, что если я объявлю объект и он не структурного типа - то тогда не будет никакой разницы, как я его передам в качестве параметра в процедуру, ByVal или ByRef?
Это Ж-ж-ж-ж неспроста (с) Винни-Пух

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 30.04.2005 (Сб) 12:21

Я не Konst_One, но одна идея есть :)
Возможно, ByRef позволяет сбрасывать объект в Nothing в вызываемой процедуре (или присваивать ему другую ссылку).
Lasciate ogni speranza, voi ch'entrate.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 30.04.2005 (Сб) 12:24

С точки зрения объекта - никакой; с точки зрения тебя - ты не сможешь установить в исходную переменную ссылку на другой объект (byval) или сможешь (byref); а с точки зрения эффективности - должно быть эффективнее byval, потому что дереференс 1 уровня, а не двух - но именно этот вопрос и был поставлен в топике.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 30.04.2005 (Сб) 12:26

alibek писал(а):Возможно, ByRef позволяет сбрасывать объект в Nothing в вызываемой процедуре (или присваивать ему другую ссылку).

Дык речь была не о наборе возможностей, а об эффективности доступа :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Ruslan Demidow
Мужчина!
Мужчина!
Аватара пользователя
 
Сообщения: 987
Зарегистрирован: 25.03.2004 (Чт) 13:39
Откуда: N.Novgorod

Сообщение Ruslan Demidow » 30.04.2005 (Сб) 12:30

GSerg писал(а):С точки зрения объекта - никакой; с точки зрения тебя - ты не сможешь установить в исходную переменную ссылку на другой объект (byval) или сможешь (byref); а с точки зрения эффективности - должно быть эффективнее byval, потому что дереференс 1 уровня, а не двух - но именно этот вопрос и был поставлен в топике.

Про дереференс подробнее, плиз, не очень понял. Видимо чтобы получить сам объект (для работы с ним) сказывается разница в количестве действий для работы с объектом со стороны VB. Так?
Это Ж-ж-ж-ж неспроста (с) Винни-Пух

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 30.04.2005 (Сб) 12:34

В одном случае будет ссылка на объект, в другом случае ссылка на ссылку на объект. Во-втором случае, по идее, работать будет медленнее.
Lasciate ogni speranza, voi ch'entrate.

Ruslan Demidow
Мужчина!
Мужчина!
Аватара пользователя
 
Сообщения: 987
Зарегистрирован: 25.03.2004 (Чт) 13:39
Откуда: N.Novgorod

Сообщение Ruslan Demidow » 30.04.2005 (Сб) 12:40

alibek писал(а):В одном случае будет ссылка на объект, в другом случае ссылка на ссылку на объект. Во-втором случае, по идее, работать будет медленнее.

Что-то я совсем запутался: ведь ByRef - это явное обращение к объекту по ссылке. А ByVal - по значению. Т.е. если я передаю объект по ссылке - то VB просто обращается к объекту по ссылке - которая и содержится в параметре, передаваемом в процедуру. А если по ByVal - то тогда (по учебнику) я получаю значение объекта - и VB, чтобы получить доступ к объекту, нужно получить опять же ту же самую ссылку на объект.
Если ты в первом случае имел в виду ByRef, а во втором ByVal - то получается что ByVal всё же медленней? Или я опять запутал и себя и других? :oops:
Это Ж-ж-ж-ж неспроста (с) Винни-Пух

Ruslan Demidow
Мужчина!
Мужчина!
Аватара пользователя
 
Сообщения: 987
Зарегистрирован: 25.03.2004 (Чт) 13:39
Откуда: N.Novgorod

Сообщение Ruslan Demidow » 30.04.2005 (Сб) 13:00

Видимо фигню в последнем посте спорол.... :oops:
Прошу извинить - больше не буду. :)
Пошёл читать вумные книжки...
Это Ж-ж-ж-ж неспроста (с) Винни-Пух

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Сообщение BV » 30.04.2005 (Сб) 13:05

Так, стоп.
Вот у нас код...

Код: Выделить всё
Option Explicit

Private Sub Form_Load()
    Dim Reply As Long, lVarOne As Long, lVarTwo As Long
    lVarOne = 128
    lVarTwo = 512
    Reply = TestFunction(lVarOne, lVarTwo)
    '...
End Sub

Private Function TestFunction(ByVal lParamOne As Long, ByRef lParamTwo As Long) As Long
    '...
End Function


Теперь объясните, что произойдёт с переменной lVarOne и переменной lVarTwo?
На сколько я понимаю: функция получит значение первой переменной и ссылку на вторую переменную, что само по себе говорит о том, что ByRef работает медленней. Поправьте, если я не прав.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 30.04.2005 (Сб) 13:26

BV, речь идёт об объектах.


2All:
Matt Curland в книге 'Advanced Visual Basic 6' писал(а):Parameters and IUnknown

Passing a variable or expression to a parameter is a lot like assigning the variable or expression to a variable of the same type as the parameter. Multiplying the two types of Set statement assignment (AddRef and QI) by the parameter modifiers (ByVal and ByRef) yields four permutations that VB must handle when passing to object parameters. We'll examine each of these permutations in terms of the IUnknown functions called in order to make it possible to pass the parameter.

ByVal, QI Required
Caller: QI the passed variable for the parameter's type and store the result in a temporary object variable. If the incoming variable is Nothing, initialize the temporary variable to Nothing. Pass the temporary variable.
Callee: AddRef the incoming ByVal parameter at the top of the function (VB-generated code does this, but COM object written in other languages might not).
Callee: Release the parameter when it leaves scope.
Caller: Release the temporary variable.

ByVal, No QI Required
Caller: AddRef the original variable and pass it.
Callee: AddRef when entering the function.
Callee: Release when exiting the function.
Caller: Release the original variable.

ByRef, QI Required
Caller: QI to get the correct type, and store the result in a temporary variable. Pass the address of the temporary variable.
Callee: Nothing to do.
Caller: If the temporary is not Nothing, QI the current reference in the temporary variable for the type of the passed parameter. Place the return reference in a second temporary variable.
Caller: Release the first temporary reference.
Caller: Release the reference in the original variable.
Caller: Move the value from the second temporary to the original variable.

ByRef, No QI Required
Caller: Pass the address of the variable (that's all).

Obviously, if you pass items of the same type, it makes the most sense to use ByRef passing, especially within your own project. Although IUnknown's overhead is not great, you need to be aware of the other implications of ByRef object parameters. If you pass ByRef to untrusted code, you give the callee the chance to invalidate your data. This isn't always a good idea. Also, if you pass an object to a method of an object in a different thread, don't use ByRef: this forces the marshaler to move your object in both directions. Of course, if you're retrieving an object instead of sending it, you need the ByRef parameter.

ByRef calls that involve mismatched types are clearly disastrous. I've rarely seen a case in which the developer really needs this capability. In most cases, the callee doesn't actually change the incoming reference, so you end up running a lot of unnecessary code, just in case. The QI that comes after the function call seems really bizarre because it happens after the function returns. If the extra QI isn't enough to scare you away from such calls, the amount of code generated in order to handle them should be. In the case of ByVal calls, the AddRef/Release call happens in the callee, so there is no extra IUnknown work to be done by the caller. However, in the case of ByRef calls, the entire IUnknown burden falls on the caller, so the code is generated everywhere the function is called with a mismatched type. The code required for a mismatched ByRef call is roughly twice the size of the code required for a mismatched ByVal. Avoid this construct unless you are truly using the parameter as a ByRef.
Изображение

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 02.05.2005 (Пн) 0:56

if you pass an object to a method of an object in a different thread, don't use ByRef: this forces the marshaler to move your object in both directions.

Ты знал это с самого начала :).

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 02.05.2005 (Пн) 19:57

Ennor писал(а):
if you pass an object to a method of an object in a different thread, don't use ByRef: this forces the marshaler to move your object in both directions.

Ты знал это с самого начала :).

Я? Ну знал, и что? :-?
Изображение


Вернуться в Народный треп

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 1

    TopList  
cron