Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.00/2: Рейтинг темы: голосов - 2, средняя оценка - 4.00
1386 / 842 / 91
Регистрация: 08.02.2017
Сообщений: 3,585
Записей в блоге: 1

Нативный CopyMemory

24.09.2023, 11:14. Показов 8685. Ответов 122

Студворк — интернет-сервис помощи студентам
Натолкнуло на рассуждения, уже ранее упомянутое.. В общем то уже ранее слышал, про замедление работы апишных функций в современных реалиях. Собственно вопрос, возможно ли копирование блока/участка с динамически меняющимся (настраиваемым) значением(?). Собственно копирование то возможно блоков разного размера, есл говорить о больших - замапив на оба блока массивы и выполнив присвоения в цикле с одного массива в другой. Тесты показывают, что блок одинакового размера копируется в 4 раза быстрей с помощью массива long, нежели битового и также в других случаях - чем меньше итераций, тем кратно быстрей. Можно копировать и большие блоки за одну операцию средствами VB. Если создать тип, с фиксированным массивом внутри, то один экземпляр типа (фактически массив) можно присвоить другому экземпляру типа. С динамическими массивами так не получится, блок перезаписывается, также как и у строк. С другой стороны у фиксированого массива свои недостатки, его нельзя замапить изменить его заголовочную структуру и даже поменять указатель на нее

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
Public Type tpArr
    arr(1000) As Integer
End Type
 
Sub ffsff
    Dim ta1 As tpArr, ta2 As tpArr
    
    Debug.Print VarPtr(ta1.arr(0))
    ta1 = ta2
    Debug.Print VarPtr(ta1.arr(0))  
End Sub
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
24.09.2023, 11:14
Ответы с готовыми решениями:

Private Declare Sub CopyMemory Lib 'kernel32' Alias 'RtlMoveMemory' (Destination As Any, Source As Any, ByVal Length As Long)
В QBasic можно написать: DEF SEG=&H40 PRINT PEEK(&H100) 'ЧИТАЕМ БАЙТ В ОПЕРАТИВКЕ ПО АДРЕСУ...

В WinXP не работает API процедура CopyMemory. Что делать?
В WinXP не работает API процедура CopyMemory. Что делать? Public Declare Sub CopyMemory Lib...

Почему указатель нулевой при CopyMemory
Здрасть. Функция CopyMemory говорит что указатель is 0. Как исправить? *Old = AllocateMemory(1)...

122
Модератор
10048 / 3894 / 883
Регистрация: 22.02.2013
Сообщений: 5,847
Записей в блоге: 79
05.10.2023, 19:09
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от HackerVlad Посмотреть сообщение
нельзя разве
Конечно нет.
0
1386 / 842 / 91
Регистрация: 08.02.2017
Сообщений: 3,585
Записей в блоге: 1
05.10.2023, 19:56  [ТС]
Замер с моего ноутбука (Win8.1), с автокадного 64битного vba. CM в 1,8 раз медленней
1.594971/0.8798828
1,81270846526378

Добавлено через 1 минуту
Прямое присвоение там 0,3320313 при прочих равных
0
1386 / 842 / 91
Регистрация: 08.02.2017
Сообщений: 3,585
Записей в блоге: 1
07.10.2023, 10:29  [ТС]
Глядя на код VBA Memory Tools, видно, что там довольно профессиональный досканально-скурпулезный подход, очнь много тестов, подчас многое не понятно. Понравились мне там конструкции типа MemByte(VarPtr(x1)) = MemByte(VarPtr(x2)). В данном случае это комбинация из парных свойств Property Let, и Property Get, и появилась идея поразбираться, как это работает. Кртакий вывод работает не очень хорошо если дело касается данных (строки, массивы) и именно это является одной из причин (возможно основной) медлительности левого Mid-а, который работает по такому же принципу, зашитому в VB. В чем подвох. В выражении
Visual Basic
1
Mid(s1, 3) = s2
s2 передается в функцию аналогично методу ByVal, т.е. сначала копируется во временную переменную, и только потом используется в функции, и при завершении фунции временная переменная удаляется полностью вместе с данными. Дальнейшие тонкости больше подходят для другой моей темы, поэтому черкану, там тоже пару строк.
0
932 / 365 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
20.11.2023, 10:17
HackerVlad, только ситхи всё возводят в абсолют
Когда человек говорит так однозначно и бескомпромиссно, как вы, да ещё, к тому же без доказательной базы, лично для меня это говорит тольео о том, что у вас очень маленький опыт тестирования, или же вы не делаете выводов, или же тесты нельзя назвать полными.

testuser2, приветствую! Судя оп тестам, получается обычная ситуация — нет универсального варианта, и, для достижения максимальной скорости, нужно уметь комбинировать приёмы в зависимости от ситуации.
Поняло не всё, но пример с Mid'ом заинтересовал — ведь метод вставки с помощью него считается (и совершенно правильно) наибыстрейшим на VBA.

За темой послежу, желаю успехов в исследованиях. Если будет что сказать — скажу
0
Модератор
10048 / 3894 / 883
Регистрация: 22.02.2013
Сообщений: 5,847
Записей в блоге: 79
20.11.2023, 10:23
Самый оптимальный и почти самый быстрый вариант - RtlMoveMemory (aka CopyMemory). Всё остальное -это микрооптимизации которые лишь в некоторых случаях могут повысить производительность.
2
932 / 365 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
20.11.2023, 10:47
The trick, полагаю, его можно считать универсальным, а также самым быстрым, но с оговоркой "если мы не хотим заморачиваться, считая биты и тому подобное".
Так получается?
0
Модератор
10048 / 3894 / 883
Регистрация: 22.02.2013
Сообщений: 5,847
Записей в блоге: 79
20.11.2023, 11:04
Jack Famous, для маленьких порций данных он может быть медленнее других способов. К примеру для копирования 4 или 8 байт быстрее использовать другие способы
1
1386 / 842 / 91
Регистрация: 08.02.2017
Сообщений: 3,585
Записей в блоге: 1
20.11.2023, 11:34  [ТС]
Цитата Сообщение от The trick Посмотреть сообщение
Самый оптимальный и почти самый быстрый вариант - RtlMoveMemory (aka CopyMemory). Всё остальное -это микрооптимизации которые лишь в некоторых случаях могут повысить производительность.
Это верно, для 32-битной платформы, но вот для vba x64, данный тезис почему-то не работает, медленный он, и даже оказался медленней порядка 2-3 раз метода, который я здесь описал.

Добавлено через 17 минут
Jack Famous, обобщенно резюмируя по теме могу сказать, что мелкие операции копировния стандартных типов (long, integer и т.д.), можно осуществлять очень быстро, благодаря манипуляций с указателями, описаными уважаемым The trick-ом.
1
932 / 365 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
20.11.2023, 11:39
testuser2, нужны примеры практического применения в сравнении со штатными способами — например, вот тут, смотрите, будет быстрее, чем Mid() = , а вот тут обнуление массива быстрее, чем ReDim динамического или Erase статического.
0
1386 / 842 / 91
Регистрация: 08.02.2017
Сообщений: 3,585
Записей в блоге: 1
20.11.2023, 12:08  [ТС]
Цитата Сообщение от Jack Famous Посмотреть сообщение
нужны примеры практического применения в сравнении со штатными способам
Не спорю, но главное определиться кому больше нужны ), ордам халявщиков, которые заходят, на, допустим, Планету Эксель возьмут готовое решение, и даже не оставят сообщение с благодарностью, или людям, которые сами вносят весомый вклад. Для вторых как говорится милости просим, и как мне кажется здесь можно споскойно обсудить многие вопросы )

Добавлено через 7 минут
Цитата Сообщение от Jack Famous Посмотреть сообщение
HackerVlad, только ситхи всё возводят в абсолют
HackerVlad, кстати хоть и пишет часто не по теме, но один из тех людей, которые вносят существенный вклад в данный раздел, все время делится своими наработками, за что ему респект )
1
932 / 365 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
20.11.2023, 12:19
testuser2, я вас умоляю) орды халявщиков просто не осиливают не то, что работу с указателями, а даже темы с готовыми решениями)))
Цитата Сообщение от testuser2 Посмотреть сообщение
HackerVlad, кстати хоть и пишет часто не по теме, но один из тех людей, которые вносят существенный вклад в данный раздел, все время делится своими наработками, за что ему респект )
за это я ему респектнул ранее, но он [в этой теме] как-то пишет вызывающе-негативно. Так нельзя, я считаю.
0
Модератор
10048 / 3894 / 883
Регистрация: 22.02.2013
Сообщений: 5,847
Записей в блоге: 79
20.11.2023, 12:41
Это верно, для 32-битной платформы, но вот для vba x64, данный тезис почему-то не работает, медленный он, и даже оказался медленней порядка 2-3 раз метода, который я здесь описал.
Скинь пожалуйста этот тест. По факту что 32битная RtlMoveMemory что 64 битная- разницы нет. 64 битная даже быстрее должна быть. Возможно ты не учитываешь тот факт что при первом вызове API функции происходит поиск API функции, который тоже занимает какое-то время. Ну и возможно что какие-то неочевидные моменты типа конверсии данных происходит - нужно глянуть код непосредственно чтобы сказать в чем дело.
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
20.11.2023, 12:55
Jack Famous, я если честно вообще не понял, за что ты меня обосрал

Добавлено через 2 минуты
testuser2, спасибо большое) приятно слышать хорошие отзывы)
0
1386 / 842 / 91
Регистрация: 08.02.2017
Сообщений: 3,585
Записей в блоге: 1
20.11.2023, 13:01  [ТС]
The trick, в модуле TestArrayCopySpeed процедура testCopySpeed, там две строчки
Visual Basic
1
2
CopyMemory ByVal StrPtr(sIn), ByVal StrPtr(sOut), size
CopyMemory ByVal StrPtr(sIn), ByVal StrPtr(sEmp), size
Если надо протестировать CopyMemory. Чтобы протестировать мою функциют надо раскомментировать строки с MemCopyLs
Расширение zip надо убрать
Вложения
Тип файла: zip РаботаСоСтрокамиVBA2.xlsm.zip (41.9 Кб, 3 просмотров)
0
1386 / 842 / 91
Регистрация: 08.02.2017
Сообщений: 3,585
Записей в блоге: 1
20.11.2023, 13:20  [ТС]
Jack Famous, давай на ты, тут все на ты , и я на сколько знаю, ты общаешься на с Щербаковым и Виталием Бедным, так что мне тем более не резон )

Не по теме:

И обоюдно хотел бы всех попросить не устраивать лишнего срача



Добавлено через 9 минут
The trick, там в тесте есть ошибка (сейчс обнаружил), я последний раз когда редактировал поменял положение параметров Dst и Src, сделал как у CopyMemory. Должно быть так.
Visual Basic
1
2
MemCopyLs StrPtr(sIn), StrPtr(sOut), size
MemCopyLs StrPtr(sIn), StrPtr(sEmp), size
0
932 / 365 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
20.11.2023, 13:24
Цитата Сообщение от HackerVlad Посмотреть сообщение
Jack Famous, я если честно вообще не понял, за что ты меня обосрал
даже не думал. Просто переписка на 3ёх страницах темы выглядит, как testuser2 показывает и объясняет, а ты ушёл в какой-то однозначный отказ.

testuser2, ну раз принято, ок. С ними общаюсь, потому что давно знакомы.
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
20.11.2023, 13:47
Мир и дружба)))
2
Модератор
10048 / 3894 / 883
Регистрация: 22.02.2013
Сообщений: 5,847
Записей в блоге: 79
21.11.2023, 19:13
Лучший ответ Сообщение было отмечено testuser2 как решение

Решение

Короче посмотрел я в чем дело. В общем в VBE7 по какой-то причине при вызове Declared функции всегда вызывается DllFunctionCall, которая каждый раз вызывает LoadLibrary/GetProcAddress пару. Почему так сделали - мне неизвестно. В VBA6/VB6 - адрес сохраняется. Прикол в том что там есть ассемблерные чанки которые такие же как и в VBA6/VB6 (NativeDeclareProlog/NativeDeclareCall/NativeDeclareEpilog), но на них в коде VBE7 нет ни одной ссылки. Вместо этого вызывается последовательность DeclareProlog/DeclareCall/DeclareEpilog в которой вызывается DllFunctionCall которая многократно замедляет любую API функцию:



К счастью есть TlbCall который не вызывает ничего лишнего, так что объявив RtlMoveMemory в tlb код будет исполняться намного-намного быстрее. Насчет самой RtlMoveMemory - там все сделано очень быстро, и ничего там тормозить не должно. Я еще поковыряю, мб как-то через Declare получится сделать через NativeDeclareEpilog. Можно кстати просто перезаписать динамические чанки и напрямую вызывать нужную функцию - нужно только глянуть какой импорт у VBE7 И есть ли доступ к ним.
5
Модератор
10048 / 3894 / 883
Регистрация: 22.02.2013
Сообщений: 5,847
Записей в блоге: 79
21.11.2023, 19:53
Во время реверса нашел очень много интересных вещей, можно выполнять к примеру код из строки по типу EbExecuteLine.
1
1386 / 842 / 91
Регистрация: 08.02.2017
Сообщений: 3,585
Записей в блоге: 1
21.11.2023, 22:20  [ТС]
Тут уж, как говориться, "маэстро взялся за дело"! Серьезная информация поступила )
Цитата Сообщение от The trick Посмотреть сообщение
Вместо этого вызывается последовательность DeclareProlog/DeclareCall/DeclareEpilog в которой вызывается DllFunctionCall которая многократно замедляет любую API функцию:
Ну конечно, я когда узнал про это замедление, сразу подумал, это искусственная вещь.
Цитата Сообщение от The trick Посмотреть сообщение
Почему так сделали - мне неизвестно.
Сейчас тупо все 64 битное, все оптимизировано под 64 бит и железки и система, и тут на тебеп.., им просто понадобилось притормозить ... мы просто промолчим, это все понятно.
Цитата Сообщение от The trick Посмотреть сообщение
можно выполнять к примеру код из строки по типу EbExecuteLine.
Я вот недавно узнал, что на кнопку можно повесить действие
Visual Basic
1
Button.OnAction = ThisWorkbook.Name & "!'" & ShName & "." & "TestButton Range(" & q & Target.Address & q & ")'
При этом строка "Range " будет интерпретировться как параметр в виде объекта Range при вызове процедуры кнопкой.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.11.2023, 22:20
Помогаю со студенческими работами здесь

CopyMemory жжет
#If Win64 Then Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"...

CopyMemory ?
Как использовать CopyMemory в алгоритмах сортировки с различными типами данных ??? Пытался...

Реализовать нативную функцию дв.в.восьм
Доброго времени суток. Собственно по тз требуется реализовать нативную функцию Excel дв.в.восьм...

memcpy/CopyMemory + 2-мерный динамический массив
Третий день в ступоре из-за ругательства компилятора. Есть проблема: нужно скопировать данные из...

CreateFileMapping ошибка в CopyMemory
Жалуестя на 1>c:\users\сергей\documents\visual studio 2010\projects\lab2\lab2\lab2.cpp(45): error...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru