Форум программистов, компьютерный форум, киберфорум
Pure Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 Аватар для winkot
0 / 0 / 0
Регистрация: 26.10.2024
Сообщений: 70

Как ускорить чтение файла

21.03.2025, 18:43. Показов 1764. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Небольшой файл весом 5 мб код
PureBasic
1
2
3
4
5
6
If ReadFile(0, "test.txt")  ; Открываем файл для чтения
  content$ = ReadString(0, #PB_File_IgnoreEOL)  ; Читаем весь файл как строку
  CloseFile(0)  ; Закрываем файл
Else
  Debug "Ошибка: не удалось открыть файл!"
EndIf
читает 1289 мс. Тот же самый файл Python с помощью аналогичного кода
Python
1
2
with open('test.txt', 'r', encoding='utf-8') as file:
    content = file.read()  # Читаем весь файл
читает за 22 мс. Что-то уж очень большая разница. Нельзя ли как то ускорить чтение файла?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.03.2025, 18:43
Ответы с готовыми решениями:

Как ускорить сохранение книги Excel 2003
Всем доброе время суток ! Перед переходом из одной книги Excel (Книга1) в другую (Книга2) бывает необходимым сохранить Книгу1....

Как ускорить загрузку БД?
Считываю в колекцию через проперти миллион рекордов за 50секунд,а надо за 30 секунд. Как оптимизировать код? VB6, Access2000 С...

Как ускорить поиск текста в текстовом файле?
День добрый! У меня есть порядка 200 текстовых файлов. Размер от 300 до 900 кб. Требуется провести поиск по их содержимому. Для...

15
Эксперт по электронике
6802 / 3229 / 335
Регистрация: 28.10.2011
Сообщений: 12,609
Записей в блоге: 7
21.03.2025, 19:14
Лучший ответ Сообщение было отмечено winkot как решение

Решение

PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
If OpenFile(0, "test.txt")
  bom = ReadStringFormat(0)
  Size.q = Lof(0)
  If Size>0
    *p=AllocateMemory(Size+2)
    If *p
      ReadData(0, *p, Size)
      content$ = PeekS(*p, -1, bom)  ; Читаем весь файл как строку
    EndIf
  EndIf
   CloseFile(0)  ; Закрываем файл
Else
  Debug "Ошибка: не удалось открыть файл!"
EndIf
1
 Аватар для winkot
0 / 0 / 0
Регистрация: 26.10.2024
Сообщений: 70
21.03.2025, 20:55  [ТС]
Спасибо! Я думаю кодировку се таи лучше устанавливать вручную? Все таки самый важный для нас вариант ANSI это или UTF8 без BOM автоматически он не определяет.
0
Эксперт по электронике
6802 / 3229 / 335
Регистрация: 28.10.2011
Сообщений: 12,609
Записей в блоге: 7
21.03.2025, 22:28
Цитата Сообщение от winkot Посмотреть сообщение
UTF8 без BOM
Если нет BOM то как определит?
Что мешает добавить BOM?
0
 Аватар для winkot
0 / 0 / 0
Регистрация: 26.10.2024
Сообщений: 70
22.03.2025, 07:14  [ТС]
Цитата Сообщение от locm Посмотреть сообщение
Если нет BOM то как определит?
С использованием статистического анализа. Да, в PureBasic к большему сожалению этого нет. Приходится писать самому. А в других языках (Python, даже в AutoIt) это делают штатные функции в одну строчку.
Цитата Сообщение от locm Посмотреть сообщение
Что мешает добавить BOM?
Конечно, в своих прогах можно добавить метку. И это было бы правильно. Для этого BOM и придумали. Это снимает много проблем с совместимостью. Но по чему то "стандартизаторы" решили и здесь добавить не разберихи и сделали вариант без BOM. И он теперь постоянно путается с ANSI. И ладно еще, если это использовали какие-нибудь программисты в своих прогах. Так нет же! В Windows по умолчанию используется UTF8 без BOM! И значит таких файлов будет большинство. И хочешь-не хочешь этот вариант надо учитывать.
0
Эксперт по электронике
6802 / 3229 / 335
Регистрация: 28.10.2011
Сообщений: 12,609
Записей в блоге: 7
23.03.2025, 14:21
Цитата Сообщение от winkot Посмотреть сообщение
В Windows по умолчанию используется UTF8 без BOM!
Почему вы так решили?
0
 Аватар для winkot
0 / 0 / 0
Регистрация: 26.10.2024
Сообщений: 70
23.03.2025, 17:43  [ТС]
Цитата Сообщение от locm Посмотреть сообщение
Почему вы так решили?
Из практики.

Добавлено через 13 минут
Ваш код по чтению файла работает отлично! Попытался я поместить содержимое файла в массив. Работает. Но обработка массива длится очень долго. Конечно, я обрабатываю большой файл весом 315 мб, содержащий 1 000 000 строк. Но суммарное время обработки составляет 85 сек. А AutoIt делает это за 7 сек. Можно ли ускорить обработку массива тоже?
PureBasic
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
; Начало отсчета времени
start_time = ElapsedMilliseconds()
 
; Открываем файл для чтения
If ReadFile(0, "test1.txt")
  ; Определяем формат строки (UTF-8, UTF-16 и т.д.)
  bom = ReadStringFormat(0)
  ; Получаем размер файла
  Size.q = Lof(0)
  If Size > 0
    ; Выделяем память для содержимого файла
    *p = AllocateMemory(Size + 2)
    If *p
      ; Читаем данные из файла в память
      ReadData(0, *p, Size)
      ; Преобразуем данные в строку
      content$ = PeekS(*p, -1, bom)  ; Читаем весь файл как строку
      ; Освобождаем память
      FreeMemory(*p)
    EndIf
  EndIf
  ; Закрываем файл
  CloseFile(0)
Else
  Debug "Ошибка: файл не найден или не может быть открыт."
  End
EndIf
read_time = ElapsedMilliseconds()
 
; Подсчитываем количество строк для создания массива
lineCount = CountString(content$, #LF$) + 1
count_time = ElapsedMilliseconds()
 
; Создаем массив для хранения строк
Dim lines.s(lineCount)
 
; Указатель на текущий символ
*ptr.Character = @content$
 
; Временная строка для накопления символов
line$ = ""
 
; Индекс для массива
index = 0
 
; Проходим по всем символам строки
While *ptr\c
  ; Если символ новой строки, сохраняем текущую строку
  If *ptr\c = #LF ; #LF — символ новой строки (\n)
    lines(index) = line$
    index + 1
    line$ = ""
  ElseIf *ptr\c <> #CR ; Игнорируем символ возврата каретки (\r)
    ; Добавляем символ к текущей строке
    line$ + Chr(*ptr\c)
  EndIf
  ; Переходим к следующему символу
  *ptr + SizeOf(Character)
Wend
 
; Добавляем последнюю строку (если файл не заканчивается символом новой строки)
If line$ <> ""
  lines(index) = line$
EndIf
 
; Конец отсчета времени
array_time = ElapsedMilliseconds()
 
; Читаем элемент под номером 3
If index >= 3
  Debug("line = " + lines(3))
Else
  Debug("Ошибка: строка 3 не существует.")
EndIf
 
; Выводим время выполнения
Debug("чтение  " + Str(read_time - start_time))
Debug("count  " + Str(count_time - read_time))
Debug("массив  " + Str(array_time - read_time))
0
Эксперт по электронике
6802 / 3229 / 335
Регистрация: 28.10.2011
Сообщений: 12,609
Записей в блоге: 7
23.03.2025, 17:58
Лучший ответ Сообщение было отмечено winkot как решение

Решение

Цитата Сообщение от winkot Посмотреть сообщение
line$ + Chr(*ptr\c)
Это будет выполнятся медленно.

Такой вариант может быть быстрее.
PureBasic
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
Procedure LoadFileToList(File.s, List Lines.s(), Format=#PB_Default)
  Protected r = #False, id
  
  If File<>""
    ClearList(Lines())
    
    id  = ReadFile(#PB_Any, File, #PB_File_SharedRead)
    If id
      If Format=#PB_Default
        Format = ReadStringFormat(id)
      Else
        ReadStringFormat(id)
      EndIf
      
      While Eof(id) = 0
       If AddElement(Lines())
          Lines() = ReadString(id, Format)
        EndIf
      Wend
      
      r = #True
      CloseFile(id)
    EndIf
  EndIf
  
  ProcedureReturn r
EndProcedure
 
NewList s.s()
LoadFileToList(File, s())
1
 Аватар для winkot
0 / 0 / 0
Регистрация: 26.10.2024
Сообщений: 70
23.03.2025, 18:09  [ТС]
Спасибо! Ваш код как всегда идеален!
А то,что при чтении файла происходит 1 000 000 обращений к SSD, для SSD не вредно?
И еще вопрос - что лучше использовать список или массив?
0
Эксперт по электронике
6802 / 3229 / 335
Регистрация: 28.10.2011
Сообщений: 12,609
Записей в блоге: 7
23.03.2025, 18:22
У винды есть файловый кэш.
1
62 / 60 / 3
Регистрация: 06.11.2010
Сообщений: 185
Записей в блоге: 1
23.03.2025, 18:40
Цитата Сообщение от winkot Посмотреть сообщение
что лучше использовать список или массив?
в 99% список. В AutoIt3 просто не другого варианта
1
 Аватар для winkot
0 / 0 / 0
Регистрация: 26.10.2024
Сообщений: 70
24.03.2025, 16:07  [ТС]
Цитата Сообщение от AZJIO Посмотреть сообщение
в 99% список.
А долгое время получение элемента по индексу не доставляет проблем?
0
Эксперт по электронике
6802 / 3229 / 335
Регистрация: 28.10.2011
Сообщений: 12,609
Записей в блоге: 7
24.03.2025, 16:21
При случайном доступе время может быть относительно большим, но при последовательном переборе элементов оно не больше чем у массива.
1
 Аватар для winkot
0 / 0 / 0
Регистрация: 26.10.2024
Сообщений: 70
24.03.2025, 18:57  [ТС]
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
NewList lst.i()
Define i.i
 
For i = 0 To 100000
    AddElement(lst())
    lst() = i
Next
 
Define start_time.q = ElapsedMilliseconds()
Define target_index = 50000
Define tmp.i
 
For i = 1 To 1000 
    ResetList(lst()) 
    For i = 0 To target_index
        If Not NextElement(lst())
            Break 
        EndIf
    Next
    tmp = lst()
Next
 
Define end_time.q = ElapsedMilliseconds()
Debug "Время доступа: " + Str(end_time - start_time) + " мс"
Время доступа: 3 мс

Python
1
2
3
4
5
6
7
8
import time
lst = [x for x in range(100000)]
 
start = time.time()
for _ in range(1000): 
    _ = lst[50000]       # Доступ к середине списка
end = time.time()
print(f"Python List: доступ по индексу — {end - start:.5f} сек")
Python List: доступ по индексу — 0.00009 сек

Что же PureBasic так отстает? :-(
0
Эксперт по электронике
6802 / 3229 / 335
Регистрация: 28.10.2011
Сообщений: 12,609
Записей в блоге: 7
24.03.2025, 19:54
Из кода питона не ясно что это двусвязный список. Больше похоже на массив.
Подробнее про двусвязный список https://ru.wikipedia.org/wiki/... ый_список)
О списке в питоне https://habr.com/ru/companies/... es/849482/
У вас в коде по сути произвольный доступ к элементу, а не перечисление когда достаточно переместится на один элемент.
В коде ошибка из-за которой время доступа меньше реального.
PureBasic
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
DisableDebugger
 
NewList lst.i()
Define i.i
 
For i = 0 To 100000
    AddElement(lst())
    lst() = i
Next
 
Define start_time.q = ElapsedMilliseconds()
Define target_index = 50000
Define tmp.i
 
For i = 1 To 1000 
  ResetList(lst())
  For e = 0 To target_index
    If Not NextElement(lst())
      Break 
    EndIf
  Next
  tmp = lst()
Next
 
Define end_time.q = ElapsedMilliseconds()
MessageRequester("", "Время доступа: " + Str(end_time - start_time) + " мс")
Он эквивалентен этому.
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DisableDebugger
 
NewList lst.i()
Define i.i
 
For i = 0 To 100000
    AddElement(lst())
    lst() = i
Next
 
Define start_time.q = ElapsedMilliseconds()
Define target_index = 50000
Define tmp.i
 
For i = 1 To 1000 
  ResetList(lst())
  If SelectElement(lst(), target_index)
    tmp = lst()
  EndIf
Next
 
Define end_time.q = ElapsedMilliseconds()
MessageRequester("", "Время доступа: " + Str(end_time - start_time) + " мс")
1
62 / 60 / 3
Регистрация: 06.11.2010
Сообщений: 185
Записей в блоге: 1
25.03.2025, 11:49
Время доступа не является единственным критерием. Список чаще всего перебирается от начала к концу и реже требуется пробежать по нему по индексам, скорее никогда. Если требуется разовый доступ, например из ListView при двойном клике, то обычно для этого не требуется 3-х миллисекундный доступ, так как реакция глаз после клика обычно 400 мсек, так же дают задержку появления меню. Поэтому бороться за доли миллиссекунд в этом алгоритме не имеет смысла.
Но за то у списка преимущество, что можно добавить удалить пункт без переписывания остальных пунктов, как это проиходит в массиве, где удали второй элемент и остальные 1000 элементов надо друг за другом все переписать в предыдущий. У списка лишь изменятся указатели у первого и третьего элемента.
Поэтому я и сказал что массив в 99% не используется. Все проги, которые у меня были написаны с массивом в AutoIt3, в PureBasic все они используют список. И не вижу ни одной причины использовать массив.
В том же ListView-подобных, а также ComboBoxGadget поддерживают удаление/добавление по индексу, то есть в центре, таким же образом удаляется и в связанном списке. Также когда создаётся список структур с привязкой к ListView/Combo через SetGadgetItemData, то есть привязывается прямой доступ к памяти по указателю к элементу, то даже не понадобиться пробежка по списку, чтобы получить к нему доступ, достаточно просто обратится получить прямой указатель к структуре и взять данные.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
25.03.2025, 11:49
Помогаю со студенческими работами здесь

Как ускорить процесс выборки?
Есть таблица в эксессе с большим кол-вом записей. Около 170 000. При загрузке формы соединяюсь с базой и делаю выборку. В нее попадает ...

VBA+Word - как ускорить выполнение?
скрипт делает несложную обработку каждого абзаца текста, но выполняется слишком медленно. Можно ли на время выполнения что-то...

Пишу 30000 строк в базу Access, как ускорить?
Экспериментирую тут с заливкой большого объема данных в базу Access. Данные заливаются в одну таблицу, которая не имеет ни ключей ни...

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

Как можно оптимизировать/ускорить код?
Здравствуйте, задача примерно такого типа: на экселевском листе есть данные в 3 колоннах (обозначим a,b,c), для каждой ячейки a...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru