Можно ли использовать большую программу для мелких действий?

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Можно ли использовать большую программу для мелких действий?

Сообщение arthur2 » 10.04.2008 (Чт) 12:13

При некоторых параметрах командной строки программа делает какое-то маленькое действие и тут же выгружается:

Код: Выделить всё
Sub main()
Dim com As String
com = Command$

    Select Case com
    Case "a"
      '  здесь какое-нибудь небольшое действие
      End
    Case Else
      'а здесь основные действия программы
      Load form1
      Load form2
      Load form3
      Load form4
    End Select

End Sub


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

Проще говоря, как рациональней: создать для действия "а" отдельную вспомогательную программку, в которой ничего, кроме этого действия не будет? Или большая программа так же быстро справится с задачей, если не будет задействовать все свои формы и классы?
Артур
 
   

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Сообщение iGrok » 10.04.2008 (Чт) 12:26

Большая программка будет делать это чуть медленнее, чем маленькая, т.к. все равно она будет целиком загружаться в память.

Как именно следует поступить в данном случае надо решать, руководствуясь тем, чего все это должно делать, насколько важна скорость действия мелкой "подпрограммки", и.т.п..

*на правах оффтопа*
Один из увиденных когда-то примеров - скринсейвер.
Там было наоборот. Сама программка д.б. маааасенькой. Быстро загружаться и работать. Но есть режим "настроек", где грузятся диалоги, и.т.п. Вот он был реализован отдельной ActiveX Dll...
Ну это так. К размышлению.
label:
cli
jmp label

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

Сообщение alibek » 10.04.2008 (Чт) 12:32

До тех пор, пока ты не загрузил формы Form1, Form2, Form3, Form4, они не занимают память.
Lasciate ogni speranza, voi ch'entrate.

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Сообщение iGrok » 10.04.2008 (Чт) 12:43

Я имел в виду память, занимаемую экзешником.
А объекты - это да.
label:
cli
jmp label

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 10.04.2008 (Чт) 13:43

alibek
Это-то как раз понятно, почему вопрос и возник.

iGrok
Если я правильно понял, файл экзешника всё равно загружается весь? И чуть медленнее всё-же будет?

Спасибо! Хотя жаль... А вопрос в догонку: что быстрее при прочих равных: запустить экзе или создать объект из длл поздним связыванием?
Артур
 
   

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Сообщение iGrok » 10.04.2008 (Чт) 14:14

ЕМНИП, да. Экзешник все равно грузится целиком. А под объекты память не выделяется. (ну правда, все равно есть App, и.т.п..)
label:
cli
jmp label

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 10.04.2008 (Чт) 14:28

arthur2
Он не загружается в память, а маппится. Маппинги работают очень быстро. Если он не сжат конечно какой-нибудь дрянью.

iGrok
App создаётся только при первом к нему обращении.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 10.04.2008 (Чт) 15:37

Хакер
А что такое маппинги? То, на сколько быстро они работают, всё же зависит от размера файла?

Провёл эксперемент - прогнал через цикл запуск и того, и другого варианта. В общем, да - медленней. И в общем, да - совсем не на много.

А вот сам по себе запуск (даже совсем пустой программы), оказывается, действие довольно долгое.

Отсюда вопрос: если выделить присловутое "маленькое действие" не в программу, а в библиотеку, то:

Будет ли быстрее создать поздним связыванием объёкт из библиотеки, чем запускать ЕХЕ?
Артур
 
   

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 10.04.2008 (Чт) 15:59

Маппинг (в третий раз тебе пишу) - специальная фича, даруемая нам механизмом работы виртуальной памяти.

В виртуальнйо памяти вся память делится на страницы по 4кб (или по 4мб в особых случаях). Страницы могут быть file-backed или swap-backed.

Если страница swap-backed, то она действительно находится в оперативной памяти, но, когда требуется - выгружается на жесткий диск в файл подкачки, и наоборот загружается, когда она нужна.

Если страница file-backed - то данные некогда не лежат в оперативной (физической) памяти, они находятся на жестком диске и при этом, когда происходит чтение/запись в file-backed страницу, в действительности, происходит чтение/запись данных с/на жесткий диск.

Маппинг файла - это создание региона file-backed страниц, ссылающихся на файл в файловой системе какого-либо диска.

...

Для того, чтобы исполняемый файл мог корректно работать, он должен быть загружен, т.е. должен быть произведён ряд мероприятий, которые создадут все необходимые условия для его работы. Одним из таких условий является помещение всех тех данных, которые необходимы приложению в память.

При этом образ файла (т.е. данные файла) не копируются в память, происходит просто маппинг (проецирование) образа программы на АП программы.

100 запущеных программ своим образом съедёт столько же оперативки, сколько 1, т.к. образ не помещается в оператику вообще оперативку.

...

Маппинги очень быстрые по своей природе, потому как этот механизм работает на очень низком уровне.

...

Провёл эксперемент - прогнал через цикл запуск и того, и другого варианта. В общем, да - медленней. И в общем, да - совсем не на много.

Странный эксперимент. Естественно - больший файл загружается медленнее. Но работает столь же быстро, как и аналогичный по коду мелкий файл.

А вот сам по себе запуск (даже совсем пустой программы), оказывается, действие довольно долгое.

Да. Если описывать, что при этом (при запуске пустой программы) происходит - 10 страниц не хватит.

Отсюда вопрос: если выделить присловутое "маленькое действие" не в программу, а в библиотеку, то:

Будет ли быстрее создать поздним связыванием объёкт из библиотеки, чем запускать ЕХЕ?

Глупость, двойная.

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

Другое дело - выделить бОльшую часть программы в DLL и загружать только при необходимости. Вот жто чем-то поможет.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 10.04.2008 (Чт) 16:52

Хакер
Спасибо за подробный ответ!
(в третий раз тебе пишу)

Ага. Я как написал, сам сообразил. Просто в прошлые разы было про чтение файлов моей программой, а здесь - про запуск экзешника системой (понятно, что система пользуется этим способом)

Код: Выделить всё
Странный эксперимент. Естественно - больший файл загружается медленнее. Но работает столь же быстро, как и аналогичный по коду мелкий файл.

По условию задачи, программа "выплняет маленькое действие и тут же выгружатеся", то есть скорость выполнения кода как раз не важна (он мизерный), а время тратится именно на запуск.

Во-первых, позднее связывание работает значительно более медленно, чем ранее. Пожалуй, раз в десять медленнее.

Раннее связывание в данном случае мне не подходит: программа не знает, с чем будет связываться.

Во-вторых, совершенно непонятно, что в результате выделения небольшого действия в DLL изменится в лучшую сторону.


Суть в следующем: программа делает то, что написано в файле её настроек. Первый варинат - в файле настроек путь к экзешнику, который нужно запустить. Второй варинат: в файле настроек имя объекта, который нужно создать. Вопрос в том, первый или второй вариант будет работать быстрее?
Артур
 
   

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 10.04.2008 (Чт) 17:03

Раннее связывание в данном случае мне не подходит: программа не знает, с чем будет связываться.

Нет. Если программа не знает, с чем будет связываться, она не сможет связываться с этим "чем-то". Не так ли? (Я уже знаю как ты мне возразишь и на основе твоего возражения хочу продолжить мысль).

Суть в следующем: программа делает то, что написано в файле её настроек. Первый варинат - в файле настроек путь к экзешнику, который нужно запустить. Второй варинат: в файле настроек имя объекта, который нужно создать. Вопрос в том, первый или второй вариант будет работать быстрее?

Сложно сказать. Примерно одинаково. В первом случае некоторое время тратится на создание процесса (как объекта ядра), при подгрузке библы этого не требуется. Во-втором случае время тратиться на поиск информации о компоненте в реестре.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 10.04.2008 (Чт) 18:00

Хакер
Если программа не знает, с чем будет связываться, она не сможет связываться с этим "чем-то".

Ну а как тут возразить? Моя программа узнаёт, с чем ей предстоит связаться, уже после того, как запущена (а для раннего связывания надо, чтобы ещё до того, как скомпилирована).

Примерно одинаково.

Собственно, я так и думал. Для очистки совести надо бы прогнать через цикл CreateObject, но чё-йто не соображу, как это устроить. Ведь второй вызов для того-же объекта будет уже быстрее?
Артур
 
   

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 10.04.2008 (Чт) 18:05

arthur2
Тогда объясни мне, чем раннее связывание отличается от позднего (по твоему)?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 10.04.2008 (Чт) 18:31

Хакер
Позднее - когда создаю объект по имени во время работы программы
Раннее - когда ставлю ссылку на нужную библиотеку и объявляю переменную уже с нужным типом.
Артур
 
   

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 10.04.2008 (Чт) 18:49

Ага, распространённая ошибка:

Код: Выделить всё
' Якобы позднее:
Set MyObj = CreateObject("Some.Thing")

' Якобы раннее
Set MyObj = New Something


Так вот, нифига подобного. В первом случае вызывается CreateObject, а CreateObject вызывает API-функцию CoCreateInstance (предварительно преобразовав progid в CLSID).

Во втором случае вызывается __vbaNew2, а __vbaNew2 вызывает API-функцию CoCreateInstance.

Так что разницы -- никакой.

А теперь о том, как оно на самом деле:
При раннем связывании компилятор имеет информацию о типе объекта, и знает, что его метод "DoSomething" будет иметь ID равный скажем 16. При вызове точно известно, что у объекта этот метод есть, и метод сразу же вызывается.

При позднем связывании, генерируется такой код, который во время работы спрашивает у объекта - "Объект, у тебя есть метод DoSomthing". И если объект отвечает, что метод есть, - "Объект, а назови-ка ты мне dispid этого метода". И объект называет. Затем происходит ещё некоторые преобразования и у интерфейса IDispatch этого объекта вызывается метод Invoke, с передачей всех параметров вызова.

Естественно, в силу того что при позднем связывании происходит сначала обмен некоторой информацией, late-bound вызов работает медленнее.

Как это всё отражается в VB?

Элементарно, позднее связывание используется при вызове метода объекта, когда ссылка на этот объект объявлена As Object. Во всех остальных случаях используется раннее связывание.

Например:

Код: Выделить всё
Command1.Caption = "Привет!"     ' Это раннее связывание

Dim knopka As Object
Set knopka = Command1
knopka.Caption = "Пока!"                     ' А это позднее связывание
Set knopka = Nothing

Dim knopka2 As CommandButton
Set knopka2 = Command1
knopka2.Caption = "Рыба"                     ' А опять же раннее
Set knopka2 = Nothing


Как видно из примера, CreateObject и Project->References здесь ну совершенно непричём.

Можно создать объект с помощью CreateObject и присвоить ссылку переменной, тип которой, т.е. интерфейс объекта объявлен в TLB (как например CommandButton, объявленный в msvbvm60.dll/3) - это всё равно будет ранним связыванием.

Можно наоборот, подключить TLB в Project->References, создать объект с помощью New и присвоить ссылку переменной As Object - это будет позднее связывание.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 10.04.2008 (Чт) 20:22

Спасибо! Собственно, на сколько я понял, если каким-то образом можно заранее объявить переменную с нужным типом, а не object, то и CreateObject будет действовать быстро. А если объявлять её же как object, то и при подключённой библиотеке при каждом обращении к любому из свойств будут тормоза.

Но всё-таки, как это применить к моему случаю?

Скажем, в библиотеке, которую программа собирается подключить, обязательно должен быть класс с определённым именем и определённым набором свойств и методов. Тогда я смогу заранее объявить переменную с нужным типом, и CreateObject будет работать быстро?

Скажем, одна библиотека odnabiblioteka, в ней есть класс nechto:
Код: Выделить всё
Public Sub chtoToTam(odno As String, drugoe As Long)
    'некие дейсвтия с предложенными параметрами
End Sub


Вторая библиотека vtorajabiblioteka, и в ней есть такой-же класс nechto, с тем же набором процедур:
Код: Выделить всё
Public Sub chtoToTam(odno As String, drugoe As Long)
    'совсем другие действия
End Sub


Я могу сделать так:
Код: Выделить всё
Dim odno As nechto 'а не Objiect
Dim drugoe As nechto 'а не Objiect

Set odno = CreateObject("odnabiblioteka.nechto")
Set drugoe = CreateObject("vtorajabiblioteka.nechto")

odno.chtoToTam "ляляля", 10
drugoe.chtoToTam "трулюлю", 20


Если я правильно понял, и если это будет работать, то здорово!

(ах, да - в моей программе тоже должен быть класс nechto, чтобы я смог объявить переменную таким образом)
Артур
 
   

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 10.04.2008 (Чт) 20:47

Упс... не заработало...

Значит, всё-же недопонял :?
Артур
 
   

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 11.04.2008 (Пт) 1:25

Спасибо! Собственно, на сколько я понял, если каким-то образом можно заранее объявить переменную с нужным типом, а не object, то и CreateObject будет действовать быстро.

Да.

А если объявлять её же как object, то и при подключённой библиотеке при каждом обращении к любому из свойств будут тормоза.

Подключается не библиотека, а TLB. А так - да.


По поводу остального:
Тебе нужно придумать (сразу, потому что потом менять будет неудобно) интерфейс и описать его. И получить TLB с описанием этого интерфейса.
Лучше сделать это с помощью MIDL-а.
Проще слелать это с помощью ActiveXDLL-проекта. (Тогда в нём надо создать единственный класс со всеми нужными членами класса, но только с пустыми!)

Далее, в odnabiblioteka и в vtorajabiblioteka эту TLB нужно подключать. В этих библиотеках, в классах, которые ты намерен создавать, нужно написать:


Код: Выделить всё
Implements IMyCustomInterface

(где IMyCustomInterface - название интерфейса, описанного ранее.

В каждом окне кода сверху есть два комбо-бокса, в первом изначально выбрано "(General)", а во втором "(Declaration)"

Так вот, в первом комбике выбираешь свой интерфейс IMyCustomInterface, во втором - метод, который хочешь реализовать -- и реализуешь.

В свою главную программу нужно также подключать TLB с описанием интерфейса, а не создавать какой-то новый класс.


А потом:

Код: Выделить всё
Dim MyObj As IMyCustomInterface

Set MyObj = CreateObject("Some.Thing")
MyObj.DoSomethingCool                ' Раннее связывание



А код классов внутри библиотек будет выглядеть соответственно так:
Код: Выделить всё
Public Sub IMyCustomInterface_DoSomethingCool()
      ' ...
      ' ...
End Sub

Public Sub IMyCustomInterface_DoSomethingBad()
      ' ...
      ' ...
End Sub

Public Sub IMyCustomInterface_RefreshSomething()
      ' ...
      ' ...
End Sub


Вместо IMyCustomInterface следует, конечно, использовать своё собственное название. Напоминаю только, что интерфейсы принято начинать на заглавную I.

Скомпилированные продукты в первой (с описанием IMyCustonInterface) TLB нуждаться не будут -- её с с обой таскать не нужно.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 11.04.2008 (Пт) 10:04

Огромное спасибо! Кажется, наконец начинаю понимать, что такое интерфейсы и как их применить.

(Я до этого уже даже рыл в сторону Implements, но как всегда, наощупь, мне всё казалось, что класс непременно должен везде одинаково называться, и , в общем, ничего не нащупывалось :lol:

А теперь - всё очень даже понятно!

Относительно того, с чего начали: я так понял, что всё это здорово увеличит скорость работы с объектом... А на скорость создания этого объекта почти не повлияет?
Артур
 
   


Вернуться в Visual Basic 1–6

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 40

    TopList