-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathgenerate_readme.py
executable file
·310 lines (253 loc) · 9.98 KB
/
generate_readme.py
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#!/usr/bin/python3
#
# Python script that regenerates the README.md from the embedded template. Uses
# ./generate_table.awk to regenerate the ASCII tables from the various *.txt
# files.
from subprocess import check_output
nano_results = check_output(
"./generate_table.awk < nano.txt", shell=True, text=True)
micro_results = check_output(
"./generate_table.awk < micro.txt", shell=True, text=True)
samd21_results = check_output(
"./generate_table.awk < samd21.txt", shell=True, text=True)
stm32_results = check_output(
"./generate_table.awk < stm32.txt", shell=True, text=True)
samd51_results = check_output(
"./generate_table.awk < samd51.txt", shell=True, text=True)
esp8266_results = check_output(
"./generate_table.awk < esp8266.txt", shell=True, text=True)
esp32_results = check_output(
"./generate_table.awk < esp32.txt", shell=True, text=True)
print(f"""\
# Auto Benchmark
Here are the results from `AutoBenchmark.ino` for various boards.
These results show that integer division and modulus operations are incredibly
slow on 8-bit AVR processors.
**Version**: AceTime v2.4.0
**NOTE**: This file was auto-generated using `make README.md`. DO NOT EDIT.
## Dependencies
This program depends on the following libraries:
* [AceTime](https://github.com/bxparks/AceTime)
* [AceRoutine](https://github.com/bxparks/AceRoutine)
## How to Generate
This requires the [AUniter](https://github.com/bxparks/AUniter) script
to execute the Arduino IDE programmatically.
The `Makefile` has rules to generate the `*.txt` results file for several
microcontrollers that I usually support, but the `$ make benchmarks` command
does not work very well because the USB port of the microcontroller is a
dynamically changing parameter. I created a semi-automated way of collect the
`*.txt` files:
1. Connect the microcontroller to the serial port. I usually do this through a
USB hub with individually controlled switch.
2. Type `$ auniter ports` to determine its `/dev/ttyXXX` port number (e.g.
`/dev/ttyUSB0` or `/dev/ttyACM0`).
3. If the port is `USB0` or `ACM0`, type `$ make nano.txt`, etc.
4. Switch off the old microcontroller.
5. Go to Step 1 and repeat for each microcontroller.
The `generate_table.awk` program reads one of `*.txt` files and prints out an
ASCII table that can be directly embedded into this README.md file. For example
the following command produces the table in the Nano section below:
```
$ ./generate_table.awk < nano.txt
```
Fortunately, we no longer need to run `generate_table.awk` for each `*.txt`
file. The process has been automated using the `generate_readme.py` script which
will be invoked by the following command:
```
$ make README.md
```
The CPU times below are given in microseconds.
## CPU Time Changes
**v0.8 to v1.4:**
* The CPU time did not change much from
**v1.5:**
* No significant changes to CPU time.
* Zone registries (kZoneRegistry, kZoneAndLinkRegistry) are now sorted by zoneId
instead of zoneName, and the `ZoneManager::createForZoneId()` will use a
binary search, instead of a linear search. This makes it 10-15X faster for
~266 entries.
* The `ZoneManager::createForZoneName()` also converts to a zoneId, then
performs a binary search, instead of doing a binary search on the zoneName
directly. Even with the extra level of indirection, the `createForZoneName()`
is between 1.5-2X faster than the previous version.
**v1.6:**
* BasicZoneManager and ExtendedZoneManager can take an optional
LinkRegistry which will be searched if a zoneId is not found. The
`BasicZoneManager::createForZoneId(link)` benchmark shows that if the zoneId
is not found, the total search time is roughly double, because the
LinkRegistry must be search as a fallback.
* On some compilers, the `BasicZoneManager::createForZoneName(binary)` becames
slightly slower (~10%?) because the algorithm was moved into the
`ace_common::binarySearchByKey()` template function, and the compiler is not
able to optimize the resulting function as well as the hand-rolled version.
The slightly decrease in speed seemed acceptable cost to reduce duplicate code
maintenance.
**v1.7.2:**
* `SystemClock::clockMillis()` became non-virtual after incorporating
AceRoutine v1.3. The sizeof `SystemClockLoop` and `SystemClockCoroutine`
decreases 4 bytes on AVR, and 4-8 bytes on 32-bit processors. No signficant
changes in CPU time.
**v1.7.5:**
* significant changes to size of `ExtendedZoneProcessor`
* 8-bit processors
* increases by 24 bytes on AVR, due adding 1 pointer and 2
`uint16_t` to MatchingEra
* decreases by 48 bytes on AVR, by disabling
`originalTransitionTime` unless
`ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG` is enabled.
* 32-bit processors
* increases by 32 bytes on 32-bit processors due to adding
a pointer and 2 `uint16_t` to MatchingEra
* decreases by 32 bytes on 32-bit processors due to disabling
`originalTransitionTime` in Transition
* Upgrade ESP8266 Core from 2.7.4 to 3.0.2.
* AutoBenchmark indicate that things are a few percentage faster.
**v1.8.0:**
* Remove `sizeof()` Clock classes which were moved to AceTimeClock library.
* No significant changes to excution times of various benchmarks.
**v1.9.0:**
* Extract `BasicZoneProcessorCache<SIZE>` and `ExtendedZoneProcessorCache<SIZE>`
from `BasicZoneManager` and `ExtendedZoneManager`. Remove all pure `virtual`
methods from `ZoneManager`, making ZoneManager hierarchy non-polymorphic.
* Saves 1100-1300 of flash on AVR.
* No signficant changes to CPU performance.
**v1.10.0:**
* Remove support for SAMD21 boards.
* Arduino IDE 1.8.19 with SparkFun SAMD 1.8.6 can no longer upload binaries
to these boards. Something about bossac 1.7.0 not found.
* Upgrade tool chain:
* Arduino IDE from 1.8.13 to 1.8.19
* Arduino AVR from 1.8.3 to 1.8.4
* STM32duino from 2.0.0 to 2.2.0
* ESP32 from 1.0.6 to 2.0.2
* Teensyduino from 1.55 to 1.56
* Add benchmarks for `ZonedDateTime::forComponents()`.
* Add support for `fold` parameter in `LocalDateTime`, `OffsetDateTime`,
`ZonedDateTime`, and `ExtendedZoneProcessor`.
* The `ZonedDateTime::forComponents()` can be made much faster using 'fold'.
* We know exactly when we must normalize and when we can avoid
normalization.
* 5X faster on AVR processors when cached, and
* 1.5-3X faster on 32-bit processors.
**v1.11.0:**
* Upgrade ZoneInfo database so that Links are symbolic links to Zones, instead
of hard links to Zones.
* No significant changes to CPU benchmarks.
**v1.11.5**
* Upgrade tool chain
* Arduino CLI from 0.20.2 to 0.27.1
* Arduino AVR Core from 1.8.4 to 1.8.5
* STM32duino from 2.2.0 to 2.3.0
* ESP32 Core from 2.0.2 to 2.0.5
* Teensyduino from 1.56 to 1.57
* Upgrade TZDB from 2022b to 2022d
**v2.0**
* Use `int16_t` year fields.
* Implement adjustable epoch year.
* Upgrade to TZDB 2022f.
* AVR:
* sizeof(LocalDate) increases from 3 to 4
* sizeof(BasicZoneProcessor) increases from 116 to 122
* sizeof(ExtendedZoneProcessor) increases from 436 to 468
* sizeof(TransitionStorage) increases from 340 to 364
* ZonedDateTime::forEpochSeconds() slower by 5-10%
* ESP8266
* sizeof(LocalDate) increases from 3 to 4
* sizeof(BasicZoneProcessor) remains at 164
* sizeof(ExtendedZoneProcessor) increases from 540 to 588
* sizeof(TransitionStorage) increases from 420 to 452
* ZonedDateTime::forEpochSeconds() slower by 0-10%
**v2.1.1**
* Upgrade to TZDB 2022g.
* Add `ZonedExtra`.
* Unify fat and symbolic links.
* Not much difference in execution times, except:
* `ZonedDateTime::forComponents()` using the `BasicZoneProcessor`
becomes ~50% slower due to the extra work needed to resolve gaps and
overlaps.
* `ZonedDateTime::forEpochSeconds()` using `BasicZoneProcessors` remains
unchanged.
* `ExtendedZoneProcessor` is substantially faster on AVR processors.
Maybe it should be recommended ove `BasicZoneProcessor` even on AVR.
**v2.2.0**
* Upgrade tool chain
* Arduino AVR from 1.8.5 to 1.8.6
* STM32duino from 2.3.0 to 2.4.0
* ESP8266 from 3.0.2 to 3.1.2 failed, reverted back to 3.0.2
* ESP32 from 2.0.5 to 2.0.7
* Add support for Seeed XIAO SAMD21
* Seeeduino 1.8.3
* Upgrade to TZDB 2023b
**v2.2.2**
* Upgrade to TZDB 2023c
**v2.2.3**
* Add support for Adafruit ItsyBitsy M4
* Using Adafruit SAMD Boards 1.7.11
* Remove Teensy 3.2
* Nearing end of life. Moved to Tier 2 (should work).
* Upgrade tool chain
* Seeeduino SAMD Boards 1.8.4
* STM32duino Boards 2.5.0
* ESP32 Boards 2.0.9
**v2.3.0**
* Add benchmarks for `CompleteZoneProcessor` and related classes
* Replace labels of `BasicZoneManager::createForXxx()` with
`BasicZoneRegistrar::findIndexForXxx()`, because those are the methods which
are actually being tested.
**v2.4.0**
* Support %z format.
* Upgrade to TZDB 2024b.
* Upgrade Arduino CLI to 1.1.1
* Almost no change in execution times.
## Arduino Nano
* 16MHz ATmega328P
* Arduino IDE 1.8.19, Arduino CLI 1.1.1
* Arduino AVR Boards 1.8.6
```
{nano_results}
```
## Sparkfun Pro Micro
* 16 MHz ATmega32U4
* Arduino IDE 1.8.19, Arduino CLI 1.1.1
* SparkFun AVR Boards 1.1.13
```
{micro_results}
```
## Seeed Studio XIAO SAMD21
* SAMD21, 48 MHz ARM Cortex-M0+
* Arduino IDE 1.8.19, Arduino CLI 1.1.1
* Seeeduino 1.8.4
```
{samd21_results}
```
## STM32 Blue Pill
* STM32F103C8, 72 MHz ARM Cortex-M3
* Arduino IDE 1.8.19, Arduino CLI 1.1.1
* STM32duino 2.5.0
```
{stm32_results}
```
## Adafruit ItsyBitsy M4 SAMD51
* SAMD51, 120 MHz ARM Cortex-M4
* Arduino IDE 1.8.19, Arduino CLI 1.1.1
* Adafruit SAMD 1.7.11
```
{samd51_results}
```
## ESP8266
* NodeMCU 1.0 clone, 80MHz ESP8266
* Arduino IDE 1.8.19, Arduino CLI 1.1.1
* ESP8266 Boards 3.0.2
```
{esp8266_results}
```
## ESP32
* ESP32-01 Dev Board, 240 MHz Tensilica LX6
* Arduino IDE 1.8.19, Arduino CLI 1.1.1
* ESP32 Boards 2.0.9
```
{esp32_results}
```
Note: Once the benchmark of the function under test becomes smaller than the
duration of an empty loop, the numbers become unreliable.
""")