Опубликовано:
Исправлено:
Версия документа: 1.0
Секреты и хитрости
В этой статье собраны советы по написанию быстрого и компактного кода. Некоторые советы специфичны для фрибейсика, некоторые для всех языков программирования, некоторые для операционной системы Windows.
Деление чисел с плавающей запятой
Если у вас числа с плавающей запятой (Single или Double), то для повышения точности вычислений лучше не делить на N
, а умножать на десятичную дробь из (1 / N)
.
Например, вместо деления на 2,0 следует умножать на 0,5; вместо деления на 3,0 — умножать 0,3(3), и так далее:
' У этой операции относительная погрешность будет больше
Dim Result As Double = 1.5 / 2.0
' Так будет точнее
Dim Result As Double = 1.5 * 0.5
Объявление переменных вместе с инициализирующим значением
В старом стиле бейсика приходилось сначала объявлять переменную, а потом присваивать ей значение:
Dim Width As Integer
Width = 640
Dim Height As Integer
Height = 480
В новом стиле переменные можно объявлять вместе с инициализирующим значением:
Dim Width As Integer = 640
Dim Height As Integer = 480
Используйте объявления переменных в новом стиле, это работает быстрее. В старом стиле получается, что сначала переменные будут инициализированы, а потом им присваивается значение.
Прекращение инициализации переменных по умолчанию
При объявлении новой переменной ей сразу же присваивается значение по умолчанию, если мы не сделали это сами:
- целочисленным переменным присваивается значение 0;
- логическиепеременные получают значение
False
; - строки фиксированной длины типа
ZString
иWString
заполняются нулевыми символами на всю их длину; - все элементы массива обнуляются.
Если нам не требуется инициализация переменных, для этого переменной нужно присвоить специальное значение Any
:
' Этой переменной значение по умолчанию не будет присвоено
' Сейчас в ней находится так называемый «мусор»
Dim Count As Integer = Any
В случае со строками необходимо поставить нулевой символ самостоятельно:
' Память под строку выделена
Dim Value As WString * (MAX_BUFFER_LENGTH + 1) = Any
' Не забываем установить нулевой символ:
Value[0] = 0
Массивы без инициализации дескриптора массива
Массив во фрибейсике — это встроенный объект (дескриптор массива), в котором хранится размер каждого из измерений и указатель на данные. При объявлении массива фрибейсик автоматически создаёт дескриптор массива и инициализирует его поля. Это необходимо для контроля за границами и передачи массива в подпрограммы.
Однако если массив объявлен внутри структуры или с модификатором Shared, то фрибейсик будет контролировать границы массива на этапе компиляции без создания дескриптора массива.
Воспользуемся этой особенностью и создадим структуру, содержащую в себе массив фиксированной длины:
Const INTEGERVECTOR_CAPACITY = 512
Type IntegerVector
Buffer(INTEGERVECTOR_CAPACITY - 1) As Integer
End Type
Теперь компилятор знает размер массива, и мы можем использовать экземпляр структуры с массивом внутри:
Dim Vector As IntegerVector = Any
For i As Integer = 0 To INTEGERVECTOR_CAPACITY - 1
Vector.Buffer(i) = i
Next
Проверка строк на пустоту
Если нужно проверить не пуста ли строка, то следует использовать функцию Len
:
If Len(s) Then
' строка не пуста
End If
Сравнение строки с литеральной константой ""
работает медленнее, потому что требует сравнения символьных данных:
If s = "" Then
' строка пуста
' этот код работает медленнее
End If
Использование строковых констант
Необходимо использовать строковые константы везде. Это исключает дублирование.
Const MyConst = "Это константа"
Быстрая очистка (обнуление) строки
Для этого достаточно присвоить 0 первому символу в строке, то есть символу под индексом 0:
Dim Value As WString * (MAX_BUFFER_LENGTH + 1) = Any
Value[0] = 0
Получение символа в строке
Новички нередко используют функцию Mid
для получения единственного символа в строке, однако есть способ проще.
Строка — это массив символов, следовательно, к ней можно применять индексирование по указателю:
' Строка длиной в 99 символов (+1 на нулевой)
Dim s As WString * (99 + 1) = Any
' Получение пятого символа в строке
Dim charCode As Integer = s[4]
Посимвольный обход строки
Предыдущий подход можно применять для посимвольного обхода строки в цикле. Проверяя текущий символ, цикл остановится как только встретится нулевой, обозначающий конец строки. Таким образом вычислять длину строки заранее не нужно:
Dim Value As WString * (MAX_BUFFER_LENGTH + 1) = Any
Dim i As Integer
Do While Value[i] <> 0
' Что‐то сделать с символом
' Например, вывести на консоль
Print Value[i]
' Сдвигаем индекс на следующий символ
i += 1
Loop
Если заранее известно, что строки будут ненулевой длины, то условие выхода из цикла While s[i] <> 0
можно поставить после Loop
.
Выравнивание структур
В объявлении структур старайся располагать поля по убыванию их размера. Особенно нужно уделить внимание группировке вместе переменных, чей размер меньше текущей архитектуры: Byte, Short, Long, Boolean, их массивы и структуры с ними.
Например, обращение к переменной с типом Integer по выровненному адресу занимает всего один такт процессора, а если переменная не выровнена, то два такта на архитектуре i386. На некоторых архитектурах читать по невыровненному адресу вообще нельзя. Так происходит потому, что невыровненная переменная располагается в нескольких ячейках памяти: часть в одной и часть в следующей.
Такой код работает медленно:
Type Foo
Field1 As Boolean
Field2 As Integer
End Type
Такой код работает быстро:
Type Bar
Field2 As Integer
Field1 As Boolean
End Type