Буфер для текста.

Тема в разделе "WASM.WIN32", создана пользователем Valentin, 1 фев 2009.

  1. Valentin

    Valentin Member

    Публикаций:
    0
    Регистрация:
    2 ноя 2007
    Сообщения:
    128
    leo

    Кстати у меня скорость обработки инфы в сотни раз быстрее, чем подобные в моей области сделаны на Васиках.
     
  2. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Valentin
    Дело не столько в самом Васике или асме, сколько в неверном (бездумном) использовании стандартных средств языка. Если для твоей задачи бесхитростно юзать склейку динамических строк в виде S=S+S1, то тормоза будут по любому - и в васике, и в дельфях и С++, т.к. при достаточно большой длине S будут возникать перераспределения памяти под S с копированием больших объемов данных из одного блока памяти в другой - а тут тебе и тормоза чтения\записи из-за невлезания данных в кэш процессора и отказы страниц и т.п., и все это может повторяться десятки-сотни раз. А если сразу выделить под результирующую строку блок памяти достаточно большого размера, то ничего этого не будет и скорость склейки будет значительно выше - и в си, и в дельфях, и в васике (если юзать функции АПИ CopyMemory и т.п.)
     
  3. Valentin

    Valentin Member

    Публикаций:
    0
    Регистрация:
    2 ноя 2007
    Сообщения:
    128
    leo

    Согласен. Я заметил ч-з прогрессбар что с накоплением строки работа идет все медленнее и медленее, понятно.
    А как указать на конец буфера?? Если Вы опытный в памяти, приведите пожалуqста пример накопления строки в памяти.
    В ссылках на Ваши посты есть примеры, но архивы 7z не открываюся/
     
  4. int2e

    int2e New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2009
    Сообщения:
    169
    Valentin
    1. Разово выделяешь 10-мегабайтовй буффер через VirtualAlloc
    2. Указатель сохраняешь в 2 переменные: указатель на буффер и в указатель на конец строки
    3. Делаешь самописную MylstrcpyA, которая после копирования, будет возвращать указатель на конец строки
    4. Формируешь строку

    Думаю, это будет самый быстрый вариант


    Пример
    Код (Text):
    1. /*---------------------------copy string-------------------------------------
    2. char* MylstrcpyA(char* dest, char* src)
    3. {
    4. char* pointer;
    5. _asm {
    6.          mov esi, [src]
    7.          mov edi, [dest]
    8.        copy_string:
    9.          movsb
    10.          cmp byte ptr [esi], 0
    11.          jnz   copy_string
    12.          mov byte ptr [edi], 0
    13.          mov [pointer], edi
    14.         }
    15.  return pointer;
    16. }
    Код (Text):
    1. /*---------------------------allocate memory-------------------------------------
    2. buff = VirtualAlloc(0, 0A00000h, MEM_COMMIT, PAGE_READWRITE); //buffer
    3. eos = (PCHAR)buff; //end of string
    4.  
    5. /*---------------------------sample----------------------------------------------
    6. eos = MylstrcpyA(eos, S1);
    7. eos = MylstrcpyA(eos, S2);
    8. eos = MylstrcpyA(eos, S3);
    9. eos = MylstrcpyA(eos, Sn);
    Дальше уже идет железная оптимизация, например замена опкодов на более быстрые, спаривающиеся, и.д. и.т.п.
    Я этих тонкостей не знаю, в этом поможет leo


    PS: если вдруг нужно онулить всю 10-мегабайтную строку, то делаешь так:
    Код (Text):
    1. eos    = (char*)buff;
    2. eos[0] = 0;
     
  5. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    в этом случае строка не будет завершена 0
    считаю необходимым сделать как минимум mov byte ptr [edi],0 после цикла - мало ли как строка еще будет использоваться
     
  6. int2e

    int2e New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2009
    Сообщения:
    169
    поправлено
     
  7. Valentin

    Valentin Member

    Публикаций:
    0
    Регистрация:
    2 ноя 2007
    Сообщения:
    128
    int2e

    Я работаю на МАSM32, нужен перевод:
    пока так:
    ; ---------------------------copy string-------------------------------------
    MylstrcpyA proc dest:lol: WORD, src:lol: WORD)

    LOCAL pointer:lol: WORD

    mov esi, [src]
    mov edi, [dest]
    copy_string:
    movsb
    cmp byte ptr [esi], 0
    jnz copy_string
    mov byte ptr [edi], 0
    mov [pointer], edi
    ret
    MylstrcpyA endp

    Теперь с памятью:
    ;---------------------------allocate memory-------------------------------------
    buff dd ?
    eos dd ?

    invoke VirtualAlloc,0, 0A00000h, MEM_COMMIT, PAGE_READWRITE
    mov buff,eax


    = (PCHAR)buff; //end of string ========= как здесь???

    ;---------------------------sample----------------------------------------------
    invoke MylstrcpyA, addr eos, addr S1
     
  8. int2e

    int2e New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2009
    Сообщения:
    169
    Код (Text):
    1. MylstrcpyA proc  dest:DWORD, src:DWORD
    2.          mov esi, [src]
    3.          mov edi, [dest]
    4.        copy_string:
    5.          movsb
    6.          cmp byte ptr [esi], 0
    7.          jnz   copy_string
    8.          mov byte ptr [edi], 0
    9.          mov eax, edi
    10.          ret
    11. MylstrcpyA endp
    Код (Text):
    1. buff dd ?
    2. eos dd ?
    3.  
    4. invoke VirtualAlloc,0, 0A00000h, MEM_COMMIT, PAGE_READWRITE
    5. mov [buff],eax
    6. mov [eos], eax
    Код (Text):
    1. invoke MylstrcpyA, dword ptr [eos], addr S1
    2. mov [eos], eax
    3. invoke MylstrcpyA, dword ptr [eos], addr S2
    4. mov [eos], eax
    5. ;...
    6. invoke MylstrcpyA, dword ptr [eos], addr Sn
    7. mov [eos], eax
     
  9. Valentin

    Valentin Member

    Публикаций:
    0
    Регистрация:
    2 ноя 2007
    Сообщения:
    128
    int2e

    Понял, большое спасибо, я почти до этого и дошел в отладчике.
     
  10. Valentin

    Valentin Member

    Публикаций:
    0
    Регистрация:
    2 ноя 2007
    Сообщения:
    128
    int2e


    Код (Text):
    1.        copy_string:
    2.          movsb
    3.          cmp byte ptr [esi], 0
    4.          jnz   copy_string
    5.          mov byte ptr [edi], 0
    6.    ;      mov eax, edi - так не получается, строка уже в eax
    7.          ret
    теперь после выполнения:
    Код (Text):
    1. invoke MylstrcpyA, dword ptr [eos], addr S1
    2. mov [eos], eax
    в [eos] -строки нет.


    И еще, где учавствует buff -?
     
  11. int2e

    int2e New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2009
    Сообщения:
    169
    По стандарту, функции возвращают значение в еах.

    Там строки и не будет. Там будет указатель на нее

    Если тебе понадобится освободить память либо занулить массив, то тут пригодится buff
     
  12. Valentin

    Valentin Member

    Публикаций:
    0
    Регистрация:
    2 ноя 2007
    Сообщения:
    128
    int2e

    А как же теперь достать собранную строку?
     
  13. Valentin

    Valentin Member

    Публикаций:
    0
    Регистрация:
    2 ноя 2007
    Сообщения:
    128
    int2e

    Все получилось, собранная строка лежит в buff.
    Еще раз огромное спасибо.