powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как правильно "прибить" копирующий поток?
61 сообщений из 61, показаны все 3 страниц
Как правильно "прибить" копирующий поток?
    #39470079
m52
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте,

У меня есть простейший поток cpyThread, который просто вызывает WinApi.Windows.CopyFile для копирования файла и больше ничего не делает. Я хочу прервать копирование, т.е. убить поток копирования cpyThread.

Делаю это вот так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
      cpyThread:=TcpyThread.Create(true);
      cpyThread.Suspended:=false; // пуск!
      // Ожидаем завершение потока (с возможностью отмены)
      
      // В случае отмены прибиваем поток жестко
      cpyThread.DoTerminate;
      TerminateThread(cpyThread.Handle, 0);
      FreeAndNil(cpyThread);


Проблемы 2 шт:
1) поток убивается несколько минут (далеко не сразу) и на одной из операций "зависает"
2) файл в конечной папке (куда копируется) остается заблокированным даже на чтение.

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

Как корректно и быстро завершить поток, копирующий файл?
Прошу использование CopyFileEx не предлагать.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39470082
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m52Прошу использование CopyFileEx не предлагать.

Тогда Вам на форум проктостоматологов.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39470083
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m52 Как корректно и быстро завершить поток, копирующий файл?
Никак. Корректно поток может завершиться только по собственной инициативе.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39470085
m52
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ладно, тогда такой вопрос:
как безопасно убить поток? Ведь понятно, что CopyFile невозможно иначе никак прервать. Поэтому я решил обернуть ее в отдельный поток и попытаться убить поток в случае отмены.

Или может подскажете другую идею, как еще можно прервать работу функции CopyFile?
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39470106
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m52, в native поток нельзя убить безопасно. Только процесс. Убийство же потока приведёт к гигантской утечке памяти, а равно как имеет ненулевой шанс подвесить процесс.

Используйте средства, позволяющие прервать операцию.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39470108
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GunSmokerУбийство же потока приведёт к гигантской утечке памяти

На размер стека потока или еще на что-то ?
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39470115
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m52Или может подскажете другую идею, как еще можно прервать работу функции CopyFile?Заменть ее на CopyFileEx, которую прервать можно.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39470117
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А, если "Ex не предлогать" - Thread.Free - ваш выбор.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39470121
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m52,
вынеси операцию копирования в отдельный процесс, не в поток.

Это не больно. :)
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39470128
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m52, если так боитесь CopyFileEx, то сделайте свой цикл копирования в потоке и прерывайте его когда угодно по флагу Terminated.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39470133
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mike,

ты что, нельзя.

Коллега уже больше года с мировой энтропией в этом направлении борется: http://www.sql.ru/forum/1211768/preryvanie-copyfile-ili-korrektnoe-ubiystvo-potoka
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39470241
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чего - то смотрю и вижу дичь, глаза на жопе и руки на лице - фейспалмом прикрывают всё это дело.

Стандартный CreateFile + SetFilePointer + ReadFile открывают файл 150 мб за долю секунды грузя в память.

Если надо быстрее, то используйте NTFS копирование. Но это явно не для ТС ибо хард поламает.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39470252
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поползал в интернете и нашёл

Исходную функцию CopyFileW

Использует CopyFileExW

А там стандартный CreateFileW + ReadFile как я и писал выше (Опыт позволил сказать как она работает)
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39470264
Mikhalich
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Наверное делать копирование ручками через overlapped операции. Прерывать можно через APC при ожидании, например, на WaitForMultipleObjectsEx.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39470653
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m52,

Можно обернуть поток в while..do, в условии поставить флаг и ждать либо естественного завершения жизни потока, либо окончания условия в while.

з.ы. задай FreeOnTerminate=false, раз уж ты используешь FreeAndNil и оберни это все в try..finally
з.ы.2 лучше сделай этот поток дополнительным и копируй файлы в OnExecute этого потока. Тогда и прибить поток сможешь в любой момент. А так ты смешал мух с котлетами
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39470655
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док, нет. У него в потоке долговременная синхртнная операция, которой начхать на все флаги и while.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39470732
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччДДок, нет
вона оно че, Михалыч. А я с телефона и не разглядел
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471137
m52
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте,

спасибо за комменты, поток все таки убивается, хотя и с задержкой.
Убивать поток придется редко, только если юзер отменяет операцию.
Но бывает (крайне редко), что с флешки файл не читается и программа впадает в бесконечность ... И тут только снятие задачи через диспетчер задач поможет. Даже поток не прибить.

Всем спасибо.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471142
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Просто удивительное стремление сделать через ж...
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471267
m52
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mike ,

Вы просто наверное не в курсе, что самая быстрая функция копирования - это именно CopyFile, особенно, по локальной сети (не CopyFileEx и не вручную по-блочно). CopyFile была выбрана из соображения скорости копирования.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471281
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m52misha mike ,

Вы просто наверное не в курсе, что самая быстрая функция копирования - это именно CopyFile, особенно, по локальной сети (не CopyFileEx и не вручную по-блочно). CopyFile была выбрана из соображения скорости копирования.

Да нет. Просто ты у нас тут местный д*р*чёк. Я уже написал как она работает, и даже сорцы дал. А ты гнёшь своё

20556671
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471440
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Няшикm52misha mike ,

Вы просто наверное не в курсе, что самая быстрая функция копирования - это именно CopyFile, особенно, по локальной сети (не CopyFileEx и не вручную по-блочно). CopyFile была выбрана из соображения скорости копирования.

Да нет. Просто ты у нас тут местный д*р*чёк. Я уже написал как она работает, и даже сорцы дал. А ты гнёшь своё

20556671
А с чего ты взял, что реализация методов вайна совпадает с реализацией методов винды?
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471463
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m52Вы просто наверное не в курсе, что самая быстрая функция копирования - это именно CopyFile, особенно, по локальной сети (не CopyFileEx и не вручную по-блочно). CopyFile была выбрана из соображения скорости копирования.
Работа с диском (сетью) -- это всегда работа с диском (сетью) и никаких чудес тут не бывает. Думаете эта функция волшебная?

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

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

Кстати, помнится, по бенчмаркам плагин bcopy для FAR Manager даже несколько быстрее, чем CopyFile. Вот где настоящая магия!
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471480
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччДНяшикпропущено...


Да нет. Просто ты у нас тут местный д*р*чёк. Я уже написал как она работает, и даже сорцы дал. А ты гнёшь своё

20556671
А с чего ты взял, что реализация методов вайна совпадает с реализацией методов винды?

Не думаю что, там будут слишком разные алгоритмы копирования. Майки ведь не пишут на каждую функции какие - то ново выдуманные функции. У них есть свой API и над этим API строят ряд других функций названных API
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471485
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Няшик,

ничем не обоснованные фантазии.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471493
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mikem52Вы просто наверное не в курсе, что самая быстрая функция копирования - это именно CopyFile, особенно, по локальной сети (не CopyFileEx и не вручную по-блочно). CopyFile была выбрана из соображения скорости копирования.
Работа с диском (сетью) -- это всегда работа с диском (сетью) и никаких чудес тут не бывает. Думаете эта функция волшебная?

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

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

Кстати, помнится, по бенчмаркам плагин bcopy для FAR Manager даже несколько быстрее, чем CopyFile. Вот где настоящая магия!

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
 do
            {
              if(UpdatePosInfo(0ULL,subadd)) break;
              if(!MyReadFile(hIn,buff,sizeof(buff),&dReaded,NULL,flags))
              {
                Log(L"ReadFile",src,NULL); Ok=FALSE; break;
              }
              subadd+=dReaded;
              if(!MyWriteFile(hOut,buff,dReaded,&dWritten,NULL,flags))
              {
                Log(L"WriteFile",dest,NULL); Ok=FALSE; break;
              }
} while(dReaded==sizeof(buff));




...

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
static BOOL MyReadFile(HANDLE hFile,PVOID lpBuffer,DWORD nNumberOfBytesToRead,PDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped,DWORD *flags)
{
  WRAPPER_PROLOG(0,BOOL)
  ReadFile(hFile,lpBuffer,nNumberOfBytesToRead,lpNumberOfBytesRead,lpOverlapped);
  WRAPPER_EPILOG(0,ERROR_SUCCESS)
}

static BOOL MyWriteFile(HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite,PDWORD lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped,DWORD *flags)
{
  WRAPPER_PROLOG(0,BOOL)
  WriteFile(hFile,lpBuffer,nNumberOfBytesToWrite,lpNumberOfBytesWritten,lpOverlapped);
  WRAPPER_EPILOG(0,ERROR_SUCCESS)
}
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471494
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччДНяшик,

ничем не обоснованные фантазии.

Да ты что!) Смотри выше, а человек говорит работает быстрее и чудеса!) А такая же реализация
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471501
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Няшик, а может и CopyFileEx3 , не помню уже. Но речь как бы не о плагинах.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471520
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m52Вы просто наверное не в курсе, что самая быстрая функция копирования - это именно CopyFile, особенно, по локальной сети (не CopyFileEx и не вручную по-блочно). CopyFile была выбрана из соображения скорости копирования.
Вот не поленился, взял исходники Windows, и знаете, что я там нашел? Именно то, что и без исходников понятно любому нормальному человеку.
\private\windows\base\client\fileopcr.c
Код: 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.
BOOL
WINAPI
CopyFileW(
    LPCWSTR lpExistingFileName,
    LPCWSTR lpNewFileName,
    BOOL bFailIfExists
    )

/*++

Routine Description:

    A file, its extended attributes, alternate data streams, and any other
    attributes can be copied using CopyFile.

Arguments:

    lpExistingFileName - Supplies the name of an existing file that is to be
        copied.

    lpNewFileName - Supplies the name where a copy of the existing
        files data and attributes are to be stored.

    bFailIfExists - Supplies a flag that indicates how this operation is
        to proceed if the specified new file already exists.  A value of
        TRUE specifies that this call is to fail.  A value of FALSE
        causes the call to the function to succeed whether or not the
        specified new file exists.

Return Value:

    TRUE - The operation was successful.

    FALSE/NULL - The operation failed. Extended error status is available
        using GetLastError.

--*/

{
    BOOL b;

    b = CopyFileExW(
            lpExistingFileName,
            lpNewFileName,
            (LPPROGRESS_ROUTINE)NULL,
            (LPVOID)NULL,
            (LPBOOL)NULL,
            bFailIfExists ? COPY_FILE_FAIL_IF_EXISTS : 0
            );

    return b;
}


Оказывается, что ваша "мегабыстрая" CopyFile внутри невозбранно вызывает "тормознутую" CopyFileEx.
Вот это поворот, не правда ли?
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471522
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mikeНяшик, а может и CopyFileEx3 , не помню уже. Но речь как бы не о плагинах.

Выглядит очень сложным, и нагромождённым... Скорее первый вариант
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471551
Жышы
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mikem52Вы просто наверное не в курсе, что самая быстрая функция копирования - это именно CopyFile, особенно, по локальной сети (не CopyFileEx и не вручную по-блочно). CopyFile была выбрана из соображения скорости копирования.
Вот не поленился, взял исходники Windows, и знаете, что я там нашел? Именно то, что и без исходников понятно любому нормальному человеку.
\private\windows\base\client\fileopcr.c
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
...

{
    BOOL b;

    b = CopyFileExW(
            lpExistingFileName,
            lpNewFileName,
            (LPPROGRESS_ROUTINE)NULL,
            (LPVOID)NULL,
            (LPBOOL)NULL,
            bFailIfExists ? COPY_FILE_FAIL_IF_EXISTS : 0
            );

    return b;
}


Оказывается, что ваша "мегабыстрая" CopyFile внутри невозбранно вызывает "тормознутую" CopyFileEx.
Вот это поворот, не правда ли?

Вполне возможно, что ТС, испытывая CopyFileEx, воткнул в нее тормозную LPPROGRESS_ROUTINE.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471556
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЖышыВполне возможно, что ТС, испытывая CopyFileEx, воткнул в нее тормозную LPPROGRESS_ROUTINE.
Это из какого места должны расти руки, что тормозным сделать проверку одного булевого флага?
Ему ж, вроде, только возможность прерывания нужна, даже не контроль прогресса копирования.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471670
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вы, кстати, ради интереса сделаете простое приложение с вызовом
Код: pascal
1.
CopyFile(Source, Dest)


и
Код: pascal
1.
CopyFileEx(Source, Dest, nil, nil, nil, 0);


и замером времени их выполнения.

И натравите его на какой-нибудь файл метров 300+ в локалке.
Будете очень удивлены, особенно если у вас Windows 10.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471689
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpБудете очень удивлены, особенно если у вас Windows 10.
Блин, откуда вы такие беретесь? Win10, сверху весь код CopyFileW, снизу начало CopyFileEx, для особо догадливых все важное выделено цветом.

И чему мне удивляться? Тому, что после первого копирования файл банально закешируется и второе копирование будет выполнено мгновенно?
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471699
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpВы, кстати, ради интереса сделаете простое приложение с вызовом
Код: pascal
1.
CopyFile(Source, Dest)


и
Код: pascal
1.
CopyFileEx(Source, Dest, nil, nil, nil, 0);


и замером времени их выполнения.

И натравите его на какой-нибудь файл метров 300+ в локалке.
Будете очень удивлены, особенно если у вас Windows 10.

misha mike...
Блин, откуда вы такие беретесь?
...


Меньше эмоций, больше тестов.

Ну, кто первым тест прогонит?
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471700
Жышы
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mikeЖышыВполне возможно, что ТС, испытывая CopyFileEx, воткнул в нее тормозную LPPROGRESS_ROUTINE.
Это из какого места должны расти руки, что тормозным сделать проверку одного булевого флага?
Ему ж, вроде, только возможность прерывания нужна, даже не контроль прогресса копирования.

Это не булевский флаг, а коллбэк. И мы не знаем, что там ТС накодил. Видимо, что-то ужасное, не зря второй год мучается.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471711
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччДМеньше эмоций, больше тестов.

Ну, кто первым тест прогонит?

Вот тебе школьная загадка из разряда какой поезд придёт раньше.

Есть две функции, А и Б. Функция А вызывает функцию Б а функция Б вызывает основный код.

Вопрос: Какая функция выполниться быстрее, А или Б
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471716
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Няшик,

тут одни люди утверждают, что одно быстрее другого, а другие возражают. По факту - голословно, и те и другие.
Тесты и их результаты никто не представил.
Кто-то на исходники вайна ссылается, кто-то вообще на исходники непонятно чего, кто-то - на конкретную версию Windows.

Какой смысл спора, если есть одни лишь утверждения, но ни тестов, ни их результатов нет?
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471722
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччДКакой смысл спора, если есть одни лишь утверждения, но ни тестов, ни их результатов нет?
Т.е. для уверенности, что 2*2=4 недостаточно знания таблицы умножения, нужно проводить масштабное тестирование?

Я показал исходник Windows 2000 (да это он), проверил в отладчике живые Windows 7 и Windows 10, показал результат дизассемблирования. И нигде не нашел никаких причин, чтобы CopyFile работала быстрее CopyFileEx.

В противовес мне выдвигаются какие-то голословные утверждения о том, что функция A, использующая в качестве реализации функцию B, должна быть быстрее ее прямого вызова. Предлагают сделать тест, который невозможно провести объективно в силу целого ряда факторов.

Это форум программистов или двач какой-то?
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471724
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччДНяшик,

тут одни люди утверждают, что одно быстрее другого, а другие возражают. По факту - голословно, и те и другие.
Тесты и их результаты никто не представил.
Кто-то на исходники вайна ссылается, кто-то вообще на исходники непонятно чего, кто-то - на конкретную версию Windows.

Какой смысл спора, если есть одни лишь утверждения, но ни тестов, ни их результатов нет?

Это всё из за незнания. Во первых - есть заполнения стэка аргументов, +1 вызов

Вот приведу пример, как 1 лишний вызов даёт просад в 1.2 %

B:
0.007186 сек.
A:
0.008768 сек.

Код: pascal
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.
program Project1;

{$R *.res}

uses
  windows, system.SysUtils;

function sprintf(S: PAnsiChar; const Format: PAnsiChar): Integer; cdecl;
  varargs; external 'msvcrt.dll';

function B(r: Integer): Integer;
begin
  Result := r;
end;

function A(r: Integer): Integer;
begin
  Result := B(r);
end;

// Измерительные функции
procedure Start(var startTime: int64);
begin
  QueryPerformanceCounter(startTime);
end;

function Stop(startTime, stopTime, iCounterPerSec: int64): AnsiString;
var
  time: Single;
begin
  if QueryPerformanceCounter(stopTime) then
  begin
    QueryPerformanceFrequency(iCounterPerSec);

    time := (0 - startTime + stopTime) / iCounterPerSec;

    SetLength(Result, 15);

    SetLength(Result, sprintf(PAnsiChar(Result), '%f сек.', time));
  end;
end;

var
  startTime, stopTime, iCounterPerSec: int64;
  I: Cardinal;
  Output: AnsiString;

  v: Integer;

begin
  try

    Writeln('B:');

    Start(startTime);

    for I := 0 to 1000000 do
      v := B(134355);

    Writeln(Stop(startTime, stopTime, iCounterPerSec));

    Writeln('A:');

    Start(startTime);

    for I := 0 to 1000000 do
      v := A(134355);

    Writeln(Stop(startTime, stopTime, iCounterPerSec));

    Readln;

    exit;
  except
    on E: Exception do

    begin
      Writeln(E.ClassName, ': ', E.Message);
      Readln;
    end;
  end;

end.

...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471725
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччДНяшик,

тут одни люди утверждают, что одно быстрее другого, а другие возражают. По факту - голословно, и те и другие.
Тесты и их результаты никто не представил.
Кто-то на исходники вайна ссылается, кто-то вообще на исходники непонятно чего, кто-то - на конкретную версию Windows.

Какой смысл спора, если есть одни лишь утверждения, но ни тестов, ни их результатов нет?

Забыл оптимизацию включить! Тогда в 1.7 %

B:
0.002759 сек.
A:
0.004741 сек.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471738
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Няшик,

Тут всё хитрее. Сделал простейшее приложение:
автор
Код: pascal
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.
program testcopy;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  WinAPI.Windows,
  System.SysUtils;

var
  Time: Cardinal;
begin
  try
    if ParamCount = 0 then
      raise Exception.Create('Usage: testcopy.exe "filename"');
    Time := GetTickCount;
    CopyFile(PChar(ParamStr(1)), PChar('.\' + ExtractFileName(ParamStr(1))), False);
    WriteLn('CopyFile: ', GetTickCount - Time, 'ms.');
    Time := GetTickCount;
    CopyFileEx(PChar(ParamStr(1)), PChar('.\' + ExtractFileName(ParamStr(1))), nil, nil, nil, 0);
    WriteLn('CopyFileEx: ', GetTickCount - Time, 'ms.');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  ReadLn;
end.



Дома в локалке при копировании по сети с ноутбука - разница в пределах погрешности. Win 10 1703.
На работе же у меня, то же самое приложение при копировании файла с файл-сервера показывало стабильную разницу в 15-20% в пользу CopyFile, причём при неоднократном запуске. Win 10 предыдущего релиза и комп на базе Core2Duo.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471740
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpНа работе же у меня, то же самое приложение при копировании файла с файл-сервера показывало стабильную разницу в 15-20% в пользу CopyFile, причём при неоднократном запуске. Win 10 предыдущего релиза и комп на базе Core2Duo.
Зашибись. На параллельно нагруженном сервере в непонятно каких условиях что-то сработало быстрее.

Вы не находите, что эта аргументация как-то слабо канает против объективной реальности, представленной кодом, который совершенно очевиден и к тому же как минимум 17 лет не менялся?
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471742
Barmaley57
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тогда уж надо, для чистоты эксперимента, дефрагментировать диск-приемник, запустить CopyFile, замерить время, удалить полученную копию, перезагрузиться, запустить CopyFileEx, замерить время....и так несколько раз. Потом посчитать мат. ожидание, дисперсию, выкинуть из эксперимента "плохие" значения и тогда уже делать выводы)))
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471743
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpНяшик,

Тут всё хитрее. Сделал простейшее приложение:
автор
Код: pascal
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.
program testcopy;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  WinAPI.Windows,
  System.SysUtils;

var
  Time: Cardinal;
begin
  try
    if ParamCount = 0 then
      raise Exception.Create('Usage: testcopy.exe "filename"');
    Time := GetTickCount;
    CopyFile(PChar(ParamStr(1)), PChar('.\' + ExtractFileName(ParamStr(1))), False);
    WriteLn('CopyFile: ', GetTickCount - Time, 'ms.');
    Time := GetTickCount;
    CopyFileEx(PChar(ParamStr(1)), PChar('.\' + ExtractFileName(ParamStr(1))), nil, nil, nil, 0);
    WriteLn('CopyFileEx: ', GetTickCount - Time, 'ms.');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  ReadLn;
end.



Дома в локалке при копировании по сети с ноутбука - разница в пределах погрешности. Win 10 1703.
На работе же у меня, то же самое приложение при копировании файла с файл-сервера показывало стабильную разницу в 15-20% в пользу CopyFile, причём при неоднократном запуске. Win 10 предыдущего релиза и комп на базе Core2Duo.


Ахахахах)) Ахахахах ХХАХАХАХххахахахаах)) Ой)) Я не могу)) Я под столом!! Ужасс - то какой...

Теперь понятно чего это у него вторая функция быстрее))) !!!!
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471745
Barmaley57
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НяшикТеперь понятно чего это у него вторая функция быстрее))) !!!!Пост то читал? Там написано, что быстрее первая. Так что причины такой радости не ясны...
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471746
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У него 2-я типа медленней.

Что в общем тоже понятно почему может быть. :)

Например:
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471748
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barmaley57НяшикТеперь понятно чего это у него вторая функция быстрее))) !!!!Пост то читал? Там написано, что быстрее первая. Так что причины такой радости не ясны...

Да какая разница - то ??? Он использует GetTickCount который живёт своей жизнью!
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471749
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну я надеюсь он более-менее адекватен, и подбирал файлы достаточного размера.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471750
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreatНу я надеюсь он более-менее адекватен, и подбирал файлы достаточного размера.

Ну если они будут мерить такими не точными способами, то у них вряд - ли получится точно замерить.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471751
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barmaley57Пост то читал? Там написано, что быстрее первая. Так что причины такой радости не ясны...
Любой, кто скажет, что в этом конкретном тесте у него первая ф-ция сработала быстрее, или врет (сразу по двум причинам), или не учитывает фоновой активности.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471771
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Запасаюсь попкорном. В свое время небезызвестный оптимизатор шаманил с флагами CreateFile и размером буфера при копировании.

"смысла в этих попытках столько же, сколько в тщательном измерении длины шага мерина, которого ведут на живодерню" (с) Виктор Конецкий
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471777
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если и "тестить", то 100+ раз скопировать файл попеременно 2-мя методами.

Так это хоть статистически не бессмысленно.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471778
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreatЕсли и "тестить", то 100+ раз скопировать файл попеременно 2-мя методами.

Так это хоть статистически не бессмысленно.

А смысл вызывать функцию А которая в конечном итоге вызовет функцию Б ?)))

По моему, от того что функцию Б вызвала функция А не станет быстрее работать.! Это маразм не понимающих людей.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471780
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Няшик,

Ну тут некоторые хотят странного. :)
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471781
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НяшикДа какая разница - то ??? Он использует GetTickCount который живёт своей жизнью!
У GetTickCount погрешность ~30 мс, этого (внезапно) за глаза хватает при измерении интервалов порядка 5 секунд, ваш Кэп.
rgreatЧто в общем тоже понятно почему может быть. :)
В данном случае речь идёт про копирование по сети. К тому же в любом случае, кэширование должно ускорять чтение/запись во *второй* раз, а не в первый, поэтому я специально CopyFileEx поставил на второе место (читай: в более выгодные условия). Если этот пример заставить копировать файл с диска на диск, то там вторая функция, за счёт кэширования, на порядок быстрее выполняется.
НяшикНу если они будут мерить такими не точными способами, то у них вряд - ли получится точно замерить.
Разницу между 3800мс и 4600мс на погрешности GetTickCount списать затруднительно. Фоновые процессы отсеиваются запуском теста ~10 раз (все 10 раз они в одни ворота играют?).
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471785
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

Кэширование НА ЗАПИСЬ может замедлять 2-е копирование. Причем значительно.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471795
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpУ GetTickCount погрешность ~30 мс
Вообще, обычно, около 15, но при запущеной дельфе... 1 мсек. т.к. дельфя, а точнее VTV который она использует, выставляет timeBeginPeriod(1).
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471797
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну раз речь заходит о тестировании скорости! Так что лучше использовать более качественные средства замера работы кода. Иначе какой толк замерять конус по окружности пластмассовой линейкой.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471798
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpВ данном случае речь идёт про копирование по сети.

Это неоднозначные факторы. Во первых влияет - скорость передачи по сети (Отдача приём на двух приёмниках, и их загруженность) Так же, запись на диск и считывание.

И представьте, вызывается в конце функция Б из А ... Т.е один и тот же код, в двух случаях.
...
Рейтинг: 0 / 0
Как правильно "прибить" копирующий поток?
    #39471807
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Совсем другое дело.

Драйв, азарт, сравнение размеров писек различными методами.

"Эх, еще бы дождь пошел!" - (с).
...
Рейтинг: 0 / 0
61 сообщений из 61, показаны все 3 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как правильно "прибить" копирующий поток?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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