powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / извлечь характер
10 сообщений из 10, страница 1 из 1
извлечь характер
    #36085782
Фотография Mr.Power
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как можно из строки извлечь (быстро) символ?
Пытался с помощью мид, слишком долго, если строка имеет размер 300 000 байт. как быть?
(Мне надо перебрать всю строку побайтно и зашифровать)
...
Рейтинг: 0 / 0
извлечь характер
    #36086078
ZVI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mr.Powerкак можно из строки извлечь (быстро) символ?
Пытался с помощью мид, слишком долго, если строка имеет размер 300 000 байт. как быть?
(Мне надо перебрать всю строку побайтно и зашифровать)
Можно, например, скопировать текст в байтовый массив и обработать каждый байт этого массива:
Код: plaintext
1.
2.
3.
4.
5.
6.
  Dim b() As Byte, i As Long, strRet As String
  b = StrConv(Txt, vbFromUnicode)
  For i =  0  To UBound(b)
    ' b(i) = ... ‘ <-- здесь кодирование
  Next
  StrRet = StrConv(b, vbUnicode)
...
Рейтинг: 0 / 0
извлечь характер
    #36086172
Фотография Mr.Power
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZVI,

спасибо, хорошая идея.
...
Рейтинг: 0 / 0
извлечь характер
    #36088788
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mr.Power,
другая идея состоит в том, чтобы сделать без копирования VB-шный массив (точнее, safearray) кодов символов:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
Option Explicit

Private Declare Function ArrPtr Lib "msvbvm60.dll" Alias "VarPtr" ( _
   pArr() As Any) As Long
   
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
   Destination As Any, Source As Any, ByVal Length As Long)

Private Const FADF_FIXEDSIZE = &H10
Private Const FADF_HAVEVARTYPE = &H80

Private Type SAFEARRAYBOUND
   cElements As Long
   lLbound As Long
End Type

'Одномерный безопасный массив
Private Type SAFEARRAY1
   cDims As Integer
   fFeatures As Integer
   cbElements As Long
   cLocks As Long
   pvData As Long
   rgsabound( 0  To  0 ) As SAFEARRAYBOUND
End Type

'Одномерный безопасный массив с описателем типа элементов
Private Type SAFEARRAY1VT
   vtType As VbVarType
   sa As SAFEARRAY1
End Type

Private Sub Test(ByVal S As String)
 Dim a As SAFEARRAY1VT   'структура заголовка одномерного безопасного массива
 Dim WChars() As Integer 'массив кодов символов
 Dim ppsaWChars As Long
 
 'Заполнение структуры заголовка одномерного безопасного массива
 a.vtType = vbInteger
 With a.sa
    .cDims =  1 
    .fFeatures = FADF_HAVEVARTYPE Or FADF_FIXEDSIZE
    .cbElements = LenB(" ")
    '.cLocks = 1
    .pvData = StrPtr(S) 'Указываем на начало строки
    With .rgsabound( 0 )
       .lLbound =  1         'или 0, по вкусу
       .cElements = Len(S) '+ 1, если хочется иметь завершающий ноль
    End With
 End With
 
 'Сопоставляем VB-шный массив Integer() и структуру
 ppsaWChars = ArrPtr(WChars())
 CopyMemory ByVal ppsaWChars, VarPtr(a.sa), LenB(ppsaWChars)
 
 'Используем элементы массива
 Dim i As Long
 For i = LBound(WChars) To UBound(WChars)
    Debug.Print ChrW$(WChars(i));
 Next i
 Debug.Print
 
 'Возвращаем указатель массива в начальное состояние
 CopyMemory ByVal ppsaWChars,  0 &, LenB(ppsaWChars)
End Sub

Private Sub Command1_Click()
 Test "У попа была собака" & vbCr & "Он её любил"
End Sub
...
Рейтинг: 0 / 0
извлечь характер
    #36089003
У vb много достоинств но скорость работы это не его козырь Если строка 300K и на обработку отводится микросекунды на плохонькой машине изучай asm быстее его ничего не бывает при работе со строками VB заметно тормозит
...
Рейтинг: 0 / 0
извлечь характер
    #36089383
Фотография Игорь Горбонос
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Автор: Нырков Сергей
> У vb много достоинств но скорость работы это не его козырь
Позволю себе не согласится, при грамотном проектировании и грамотной реализации программа написанная на VB может и не
проигрывать в скорости работы аналогу на С++ или Делфи. А учитывая что программа на VB это, как правило, back-end то
пользователь и не заметит особой разницы в скорости работы.

> Если строка 300K и на обработку отводится микросекунды на плохонькой машине изучай asm быстее его ничего не
> бывает при работе со строками VB заметно тормозит

А ты сделай свой набросок и протестируй на скорость его и пример Бенедикта и немного удивись


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
извлечь характер
    #36089431
Про ассемблер здесь злостный оффтопик, но просто посчитаем: 300 Ксимволов (600 Кбайт), 100 мкс -> ПСП только на чтение 6 ГБ/с. Не говоря про обработку и запись. Угу. Ага.
...
Рейтинг: 0 / 0
извлечь характер
    #36090120
ZVI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Использование API-функций для подмены указателей вместо копирования больших фрагментов памяти, конечно же эффективно. Но при тестовой строке 300000 байт по сравнению с более простым методом обработки байтового массива выигрыш-то небольшой. И для сохранения результата кодирования (вспомним тему) потребуется еще одно присвоение, т.е. дополнительное время на операцию с большим фрагментом памяти, хотя можно все сделать и до освобождения памяти ppsaWChars, но это всё же будет ограничением на структуру кода.

Если уж использовать API, то вне конкуренции загрузка в память скомпилированного бинарного кода, написанного на ассемблера, с использованием обратного вызова (VB+Asm).

Ради интереса провел сравнительное тестирование. Использовал тестовый Unicode-текст с 300000 символами, количество циклов для каждого метода: 100. Так как тема изначально была о кодировании, то в каждый метод, кроме VB+Asm, добавил: Число Xor 1 для имитации кодирования с паролем. В варианте VB+Asm для реального Xor- кодировани использовал более длинный пароль "Password", т.е. этот вариант - посложнее.

Результаты тестирования, полученные на моем компе:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
==================================================
TimeTest: Chars =  300000 ; Cycles =  100 
--------------------------------------------------
MidArray:      8 . 109  sec        3   699   422  char/sec
ByteArray:     1 . 108  sec       27   066   079  char/sec
SafeArray:     1 . 000  sec       30   000   000  char/sec
VbAsm:         0 . 172  sec      174   545   455  char/sec
==================================================

Код модуля 1 (все, кроме VB+Asm)
Module1
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
' Code of Module1
Option Explicit

Private Declare Function ArrPtr Lib "msvbvm60.dll" Alias "VarPtr" (pArr() As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Const FADF_FIXEDSIZE = &H10
Private Const FADF_HAVEVARTYPE = &H80

Private Type SAFEARRAYBOUND
   cElements As Long
   lLbound As Long
End Type

'Одномерный безопасный массив
Private Type SAFEARRAY1
   cDims As Integer
   fFeatures As Integer
   cbElements As Long
   cLocks As Long
   pvData As Long
   rgsabound( 0  To  0 ) As SAFEARRAYBOUND
End Type

'Одномерный безопасный массив с описателем типа элементов
Private Type SAFEARRAY1VT
   vtType As VbVarType
   sa As SAFEARRAY1
End Type

' --> Safe Array method
Private Sub Test_SafeArray(ByVal S As String)
 Dim a As SAFEARRAY1VT   'структура заголовка одномерного безопасного массива
 Dim WChars() As Integer 'массив кодов символов
 Dim ppsaWChars As Long
 'Заполнение структуры заголовка одномерного безопасного массива
 a.vtType = vbInteger
 With a.sa
    .cDims =  1 
    .fFeatures = FADF_HAVEVARTYPE Or FADF_FIXEDSIZE
    .cbElements = LenB(" ")
    '.cLocks = 1
    .pvData = StrPtr(S)     'Указываем на начало строки
    With .rgsabound( 0 )
       .lLbound =  1          'или 0, по вкусу
       .cElements = Len(S)  '+ 1, если хочется иметь завершающий ноль
    End With
 End With
 'Сопоставляем VB-шный массив Integer() и структуру
 ppsaWChars = ArrPtr(WChars())
 CopyMemory ByVal ppsaWChars, VarPtr(a.sa), LenB(ppsaWChars)
 'Используем элементы массива
 Dim i As Long
 For i = LBound(WChars) To UBound(WChars) Step  2 
    'Debug.Print ChrW$(WChars(i));
    WChars(i) = WChars(i) Xor  1  '<-- для разогрева, т.к.результат не сохранится
 Next i
 'Debug.Print
 'Возвращаем указатель массива в начальное состояние
 CopyMemory ByVal ppsaWChars,  0 &, LenB(ppsaWChars)
End Sub
' <-- End of Safe Array method

' Mid$() method
Sub Test_Mid(txt As String)
  Dim i As Long
  For i =  1  To Len(txt)
    Mid$(txt, i) = Chr$(Asc(Mid$(txt, i,  1 )) Xor  1 )
  Next
End Sub

' ByteArray method
Sub Test_ByteArray(txt As String)
  Dim b() As Byte, i As Long
  b = txt
  For i =  0  To UBound(b) Step  2 
    b(i) = b(i) Xor  1 
  Next
  txt = b
End Sub

' Time test of methods
Sub TimeTest()
  
  Dim txt As String, TestText As String, t As Date, i As Integer
  
  Const N =  100              ' <-- Test cycles amount
  Const X =  300000           ' <-- Test Unicode chars amount
  Const Pwd = "Password"    ' <-- For VB + Asm method only
  TestText = String(X, "-") ' <-- Test Unicode string
    
  ' Print test header
  Debug.Print String( 50 , "=")
  Debug.Print "TimeTest: Chars = " & X & "; Cycles = " & N
  Debug.Print String( 50 , "-")
  
  ' Test of Mid$() method
  txt = TestText
  t = Timer
  For i =  1  To N
    Test_Mid txt
  Next
  t = Timer - t
  PrintResult "MidArray", t, N, X
  
  ' Test of Byte array method
  txt = TestText
  t = Timer
  For i =  1  To N
    Test_ByteArray txt
  Next
  t = Timer - t
  PrintResult "ByteArray", t, N, X
  
  ' Test of Safe array method
  txt = TestText
  t = Timer
  For i =  1  To N
    Test_SafeArray txt
  Next
  t = Timer - t
  PrintResult "SafeArray", t, N, X
  
  ' Test of VB + Asm method
  txt = TestText
  t = Timer
  For i =  1  To N
    VbAsmCrypt txt, Pwd
  Next
  t = Timer - t
  PrintResult "VbAsm", t, N, X
    
End Sub

' Вывод результата тестирования
Private Sub PrintResult(Msg, t, N, X)
  Dim ChPerSec$
  ChPerSec = Format(N * X / t, "# ### ###")
  If Len(ChPerSec) <  11  Then ChPerSec = Space( 11  - Len(ChPerSec)) & ChPerSec
  Debug.Print Msg & ":", Format(t, "0.000") & " sec", ChPerSec & " char/sec"
End Sub


' Проверка кодирования: Xor 1
Sub HowMethodsAreWorking()
  Dim txt$, TestTxt$
  TestTxt = "1234567890qwertyйцукен"
  txt = TestTxt: Test_Mid txt: Debug.Print txt, "Test_Mid"
  txt = TestTxt: Test_ByteArray txt: Debug.Print txt, "Test_ByteArray"
  txt = TestTxt: Test_SafeArray txt: Debug.Print txt, "Test_SafeArray"; " <-- не сохраняет результат кодирования!"
  txt = TestTxt: VbAsmCrypt txt, Chr( 1 ): Debug.Print txt, "VbAsmCrypt"
End Sub


Код модуля 2 (VB+Asm)
Module2
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
' Code of Module1
' Вариант с обратным вызовом скомпилированного ASM-кода
Option Explicit

Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal ptrMC As Long, ByVal P1 As Long, ByVal P2 As Long, ByVal P3 As Long, ByVal P4 As Long) As Long
Const StrCode = "5589E55356578B450C85C074468B451485C0743F8B4D0CD1E18B550801CAF7D98B5D14D1E38B451001D8894510F7DB895D148B040A035D1032032B5D1081C30200000075038B5D1489040A81C10200000075DF31C05F5E5B89EC5DC21000"
Dim BinCode() As Byte, Ok As Boolean

Function VbAsmCrypt(Str As String, Password As String) As Boolean
    Dim i&
    If Len(Str) * Len(Password) =  0  Then Exit Function
    If Ok <> True Then
      ReDim BinCode( 93 )
      For i =  0  To  93 
        BinCode(i) = "&H" + Mid$(StrCode, i *  2  +  1 ,  2 )
      Next
      Ok = True
    End If
    CallWindowProc VarPtr(BinCode( 0 )), StrPtr(Str), Len(Str), StrPtr(Password), Len(Password)
    VbAsmCrypt = True
End Function
...
Рейтинг: 0 / 0
извлечь характер
    #36090124
ZVI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В методе Safe Array, конечно же, нужно было Private Sub Test_SafeArray(ByVal S As String)
заменить на Private Sub Test_SafeArray(S As String) .
Тогда и результат сохранится, и скорость в раза 2.5 раза выше будет.
Но метод VB+Asm все же быстрее, у меня - примерно 2.3 раза.
...
Рейтинг: 0 / 0
извлечь характер
    #36090125
ZVI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZVIВ методе Safe Array, конечно же, нужно было Private Sub Test_SafeArray(ByVal S As String)
заменить на Private Sub Test_SafeArray(S As String) .
Тогда и результат сохранится, и скорость в раза 2.5 раза выше будет.
Но метод VB+Asm все же быстрее, у меня - примерно 2.3 раза.
Предыдущие оценки быстродейсвия были неверны, привожу уточненные результаты тестирования:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
==================================================
TimeTest: Chars =  300000 ; Cycles =  100 
--------------------------------------------------
MidArray:      7 , 985  sec        3   756   879  char/sec
ByteArray:     1 , 108  sec       27   066   079  char/sec
SafeArray:     0 , 767  sec       39   133   758  char/sec
VbAsm:         0 , 172  sec      174   545   455  char/sec
==================================================
Vb+Asm метод у меня примерно в 4.5 раза быстрее метода Safe Array
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / извлечь характер
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]