├── .gitignore ├── Configs └── Default.config.gmx ├── Microtester.project.gmx ├── README.md ├── extensions ├── js_hiprec_get_timer.extension.gmx └── js_hiprec_get_timer │ ├── jshpgt.gml │ └── jshpgt.js ├── fonts ├── fnt_test.font.gmx └── fnt_test.png ├── objects ├── obj_blank.object.gmx └── obj_tester.object.gmx ├── rooms └── rm_test.room.gmx ├── scripts ├── assert.gml ├── pack.gml ├── setup_tests_here.gml ├── string_format_exp.gml ├── test_add.gml ├── test_blank.gml ├── test_update.gml └── trace.gml └── sprites ├── images └── spr_white32_0.png └── spr_white32.sprite.gmx /.gitignore: -------------------------------------------------------------------------------- 1 | /help.rtf 2 | Configs/Default/ -------------------------------------------------------------------------------- /Configs/Default.config.gmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | False 5 | 0 6 | 0 7 | false 8 | 9 | MoPub 10 | 0 11 | 0 12 | 0 13 | True 14 | True 15 | True 16 | false 17 | false 18 | True 19 | 23.0.1 20 | 0 21 | 0 22 | 23 23 | Compare 24 | 25 | 26 | 0 27 | 0 28 | 0 29 | false 30 | 0 31 | 0 32 | 0 33 | 34 | 35 | -1 36 | Configs\Default\android\icons\icon_hdpi.png 37 | Configs\Default\android\icons\icon_ldpi.png 38 | Configs\Default\android\icons\icon_mdpi.png 39 | Configs\Default\android\icons\icon_xhdpi.png 40 | Configs\Default\android\icons\icon_xxhdpi.png 41 | Configs\Default\android\icons\icon_xxxhdpi.png 42 | auto 43 | -1 44 | 0 45 | 46 | -1 47 | 1 48 | 9 49 | 0 50 | 0 51 | 0 52 | 0 53 | True 54 | True 55 | True 56 | True 57 | 2 58 | Configs\Default\android\icons\ouyaIcon.png 59 | companyname 60 | com 61 | Compare 62 | 8 63 | Configs\Default\android\portrait_splash.png 64 | 0 65 | 66 | -1 67 | 68 | 4 69 | Configs\Default\android\splash.png 70 | 0 71 | 23.1.1 72 | 23 73 | 1024 74 | false 75 | 0 76 | false 77 | false 78 | 79 | MoPub 80 | 0 81 | true 82 | true 83 | false 84 | false 85 | false 86 | True 87 | True 88 | True 89 | false 90 | false 91 | True 92 | Configs\Default\amazonfire\icons\background.png 93 | Configs\Default\amazonfire\icons\banner.png 94 | 23.0.1 95 | 0 96 | 0 97 | 23 98 | Compare 99 | 100 | 101 | false 102 | false 103 | 0 104 | 0 105 | 106 | false 107 | Configs\Default\amazonfire\icons\icon_hdpi.png 108 | Configs\Default\amazonfire\icons\icon_ldpi.png 109 | Configs\Default\amazonfire\icons\icon_mdpi.png 110 | Configs\Default\amazonfire\icons\icon_xhdpi.png 111 | Configs\Default\amazonfire\icons\icon_xxhdpi.png 112 | Configs\Default\amazonfire\icons\icon_xxxhdpi.png 113 | auto 114 | true 115 | true 116 | Configs\Default\amazonfire\icons\large_icon.png 117 | false 118 | 119 | 0 120 | 1 121 | 9 122 | 0 123 | 0 124 | True 125 | True 126 | True 127 | True 128 | companyname 129 | com 130 | Compare 131 | 8 132 | Configs\Default\amazonfire\portrait_splash.png 133 | 0 134 | 135 | -1 136 | 137 | Configs\Default\amazonfire\icons\small_icon.png 138 | Configs\Default\amazonfire\splash.png 139 | 0 140 | 23.1.1 141 | 23 142 | 1024 143 | false 144 | 0 145 | false 146 | false 147 | 148 | MoPub 149 | 0 150 | true 151 | true 152 | false 153 | false 154 | 0 155 | True 156 | True 157 | True 158 | false 159 | false 160 | True 161 | Configs\Default\androidtv\icons\background.png 162 | Configs\Default\androidtv\icons\banner.png 163 | 23.0.1 164 | 0 165 | 0 166 | 23 167 | Compare 168 | 169 | 170 | 0 171 | false 172 | 0 173 | 0 174 | 175 | false 176 | Configs\Default\androidtv\icons\icon_hdpi.png 177 | Configs\Default\androidtv\icons\icon_ldpi.png 178 | Configs\Default\androidtv\icons\icon_mdpi.png 179 | Configs\Default\androidtv\icons\icon_xhdpi.png 180 | Configs\Default\androidtv\icons\icon_xxhdpi.png 181 | Configs\Default\androidtv\icons\icon_xxxhdpi.png 182 | auto 183 | true 184 | -1 185 | Configs\Default\androidtv\icons\large_icon.png 186 | 0 187 | 188 | -1 189 | 1 190 | 0 191 | 0 192 | companyname 193 | com 194 | Compare 195 | 8 196 | 0 197 | 198 | -1 199 | 200 | Configs\Default\androidtv\icons\small_icon.png 201 | Configs\Default\androidtv\splash.png 202 | 23.1.1 203 | 1024 204 | false 205 | True 206 | 1 207 | 208 | nil 209 | False 210 | false 211 | false 212 | true 213 | 0 214 | microtester 215 | True 216 | 0 217 | 218 | 219 | false 220 | False 221 | false 222 | 0 223 | nil 224 | False 225 | {93709B73-C15F-48A4-A050-1E9918296AA0} 226 | 271880499 227 | 0 228 | false 229 | true 230 | true 231 | 2 232 | 0 233 | 234 | Supersonic Ads 235 | True 236 | False 237 | Created with GameMaker: Studio 238 | False 239 | 240 | 241 | 0 242 | 0 243 | 244 | html5game 245 | 0 246 | 0 247 | 248 | Configs\Default\html5\fav.ico 249 | -1 250 | -1 251 | 252 | -1 253 | True 254 | True 255 | index.html 256 | -1 257 | True 258 | Configs\Default\html5\splash.png 259 | 2048 260 | 0 261 | True 262 | False 263 | nil 264 | 0 265 | 266 | True 267 | false 268 | false 269 | 270 | iAds 271 | 272 | 0 273 | < Press refresh to fetch certificate list from Mac> 274 | 3 275 | Compare 276 | 277 | 278 | 0 279 | false 280 | 281 | false 282 | 283 | 284 | 0 285 | Configs\Default\ios\icons\icon114.png 286 | Configs\Default\ios\icons\icon120.png 287 | Configs\Default\ios\icons\icon144.png 288 | Configs\Default\ios\icons\icon152.png 289 | Configs\Default\ios\icons\icon167.png 290 | Configs\Default\ios\icons\icon57.png 291 | Configs\Default\ios\icons\icon72.png 292 | Configs\Default\ios\icons\icon76.png 293 | Configs\Default\ios\icons\app\ipad_152.png 294 | Configs\Default\ios\icons\app\ipad_76.png 295 | Configs\Default\ios\icons\notification\ipad_20.png 296 | Configs\Default\ios\icons\notification\ipad_40.png 297 | Configs\Default\ios\icons\app\ipad_pro_167.png 298 | Configs\Default\ios\icons\settings\ipad_29.png 299 | Configs\Default\ios\icons\settings\ipad_58.png 300 | Configs\Default\ios\icons\spotlight\ipad_40.png 301 | Configs\Default\ios\icons\spotlight\ipad_80.png 302 | Configs\Default\ios\icons\app\iphone_120.png 303 | Configs\Default\ios\icons\app\iphone_180.png 304 | Configs\Default\ios\icons\notification\iphone_40.png 305 | Configs\Default\ios\icons\notification\iphone_60.png 306 | Configs\Default\ios\icons\settings\iphone_58.png 307 | Configs\Default\ios\icons\settings\iphone_87.png 308 | Configs\Default\ios\icons\spotlight\iphone_120.png 309 | Configs\Default\ios\icons\spotlight\iphone_80.png 310 | Configs\Default\ios\icons\itunes\itunes_1024.png 311 | -1 312 | Configs\Default\ios\iPadRetinasplash.png 313 | Configs\Default\ios\iPadRetinasplashPortrait.png 314 | Configs\Default\ios\iPadsplash.png 315 | Configs\Default\ios\iPadsplashPortrait.png 316 | Configs\Default\ios\iPhone5splash.png 317 | Configs\Default\ios\iPhone5splashPortrait.png 318 | Configs\Default\ios\iPhone6splash.png 319 | Configs\Default\ios\iPhone6splashPortrait.png 320 | Configs\Default\ios\iPhone6Plussplash.png 321 | Configs\Default\ios\iPhone6PlussplashPortrait.png 322 | Configs\Default\ios\iPhone7splash.png 323 | Configs\Default\ios\iPhone7splashPortrait.png 324 | Configs\Default\ios\iPhone7Plussplash.png 325 | Configs\Default\ios\iPhone7PlussplashPortrait.png 326 | Configs\Default\ios\iPhone8splash.png 327 | Configs\Default\ios\iPhone8splashPortrait.png 328 | Configs\Default\ios\iPhone8Plussplash.png 329 | Configs\Default\ios\iPhone8PlussplashPortrait.png 330 | Configs\Default\ios\IphoneRetinasplash.png 331 | Configs\Default\ios\IphoneRetinasplashPortrait.png 332 | Configs\Default\ios\iPhonesplash.png 333 | Configs\Default\ios\iPhonesplashPortrait.png 334 | Configs\Default\ios\iPhonesesplash.png 335 | Configs\Default\ios\iPhonesesplashPortrait.png 336 | Configs\Default\ios\iPhonexsplash.png 337 | Configs\Default\ios\iPhonexsplashPortrait.png 338 | 1 339 | 0 340 | -1 341 | -1 342 | -1 343 | -1 344 | 345 | 0 346 | -1 347 | 348 | Configs\Default\ios\splash.png 349 | 0 350 | 351 | 1024 352 | false 353 | 354 | Compare 355 | 0 356 | 0 357 | http://www.Compare.com 358 | Configs\Default\linux\icon64.png 359 | -1 360 | Compare 361 | 362 | -1 363 | -1 364 | Compare 365 | 0 366 | Configs\Default\linux\splash.png 367 | 0 368 | 0 369 | 2048 370 | 0 371 | 1 372 | 0 373 | 255 374 | nil 375 | false 376 | 377 | 378 | 0 379 | 0 380 | 0 381 | (c)2016 CompanyName Ltd... 382 | 0 383 | Compare 384 | 0 385 | 0 386 | 0 387 | Configs\Default\mac\icon512.png 388 | -1 389 | 1 390 | 0 391 | 0 392 | ~/GameMaker-Studio/Compare 393 | -1 394 | -1 395 | -1 396 | Developer ID Application: 397 | 0 398 | Configs\Default\mac\splash.png 399 | 0 400 | 0 401 | 402 | 2048 403 | false 404 | false 405 | true 406 | 0 407 | 0 408 | -1 409 | 410 | Memo1 411 | Memo1 412 | 413 | 414 | 0 415 | 2048 416 | 1.00 417 | 0 418 | 0 419 | -1 420 | 1 421 | 0 422 | 423 | Memo1 424 | 425 | 426 | 0 427 | 0 428 | 2048 429 | 0 430 | 0 431 | -1 432 | 1 433 | 0 434 | 435 | Memo1 436 | Memo1 437 | 438 | 439 | 0 440 | 0 441 | 0 442 | 2048 443 | true 444 | 0 445 | true 446 | -1 447 | true 448 | 0 449 | 450 | True 451 | true 452 | True 453 | True 454 | 1 455 | False 456 | false 457 | 0 458 | 2 459 | 0 460 | <none> 461 | 0 462 | 9223372036854775807 463 | 1 464 | Default 465 | http://yourdomain/Compare 466 | 0 467 | Compare 468 | 0 469 | 470 | 0 471 | 472 | 473 | Configs\Default\tizen\icon117.png 474 | -1 475 | 1 476 | 0 477 | 478 | 0 479 | 0 480 | 0 481 | Configs\Default\tizen\splash.png 482 | 1024 483 | False 484 | 485 | 0 486 | < Press refresh to fetch certificate list from Mac> 487 | Compare 488 | Configs\Default\tvos\icons\icon1280.png 489 | Configs\Default\tvos\icons\icon400.png 490 | -1 491 | 1 492 | 0 493 | -1 494 | Configs\Default\tvos\splash.png 495 | 0 496 | 2048 497 | False 498 | True 499 | False 500 | 100 501 | 0 502 | 503 | 504 | 505 | 1 506 | 0 507 | 508 | 0 509 | 510 | 0 511 | 512 | 0 513 | 514 | 0 515 | 516 | 0 517 | Windows8_TemporaryKey.pfx 518 | Compare 519 | 0 520 | -1 521 | -1 522 | -1 523 | Configs\Default\Windows8\logos\logo150.png 524 | #000000 525 | light 526 | 1 527 | 0 528 | 0 529 | Win8NativeRunner_TemporaryKey.pfx 530 | x86 531 | YourPackageDisplayName 532 | YourPackageName 533 | -1 534 | -1 535 | YourPublisherName 536 | CN=YoyoGames 537 | 0 538 | false 539 | 0 540 | Configs\Default\Windows8\logos\logo30.png 541 | #000000 542 | Configs\Default\Windows8\splashscreen.png 543 | Configs\Default\Windows8\logos\logo50.png 544 | 1024 545 | Configs\Default\Windows8\logos\logo310.png 546 | 0 547 | 0 548 | WinUWPRunner_TemporaryKey.pfx 549 | Compare 550 | 0 551 | 0 552 | -1 553 | -1 554 | -1 555 | Configs\Default\WindowsUAP\logos\LargeLogo.scale-100.png 556 | Configs\Default\WindowsUAP\logos\Logo.scale-100.png 557 | #000000 558 | light 559 | 1 560 | 0 561 | 0 562 | x86 563 | YourPackageDisplayName 564 | YourPackageName 565 | -1 566 | -1 567 | YourPublisherName 568 | CN=Sandbox 569 | 0 570 | false 571 | 0 572 | Configs\Default\WindowsUAP\logos\SmallLogo.scale-100.png 573 | Configs\Default\WindowsUAP\logos\SmallishLogo.scale-100.png 574 | #000000 575 | Configs\Default\WindowsUAP\SplashScreen.scale-100.png 576 | Configs\Default\WindowsUAP\logos\StoreLogo.scale-100.png 577 | 1024 578 | Configs\Default\WindowsUAP\logos\WideLogo.scale-100.png 579 | clBlack 580 | False 581 | 0 582 | 583 | 584 | False 585 | 586 | 0 587 | Configs\Default\windows\runner_icon.ico 588 | Configs\Default\windows\License.txt 589 | 0 590 | 1 591 | Configs\Default\windows\RunnerInstaller.nsi 592 | 593 | 0 594 | Configs\Default\windows\Runner_finish.bmp 595 | Configs\Default\windows\Runner_header.bmp 596 | 0 597 | 10 598 | #000000 599 | Configs\Default\windows\splash.png 600 | 0 601 | 2048 602 | 0 603 | 1 604 | Configs\Default\WinPhone\SplashScreenImage480.jpg 605 | Configs\Default\WinPhone\SplashScreenImage720.jpg 606 | Configs\Default\WinPhone\SplashScreenImage.jpg 607 | 608 | 0 609 | 610 | 0 611 | 612 | You 613 | 0 614 | Configs\Default\WinPhone\CycleSmall.png 615 | Configs\Default\WinPhone\CycleWide1.png 616 | Configs\Default\WinPhone\CycleWide2.png 617 | Configs\Default\WinPhone\CycleWide3.png 618 | Configs\Default\WinPhone\CycleWide4.png 619 | Configs\Default\WinPhone\CycleWide5.png 620 | Configs\Default\WinPhone\CycleWide6.png 621 | Configs\Default\WinPhone\CycleWide7.png 622 | Configs\Default\WinPhone\CycleWide8.png 623 | Configs\Default\WinPhone\CycleWide9.png 624 | YourDescription 625 | Compare 626 | 627 | 628 | Configs\Default\WinPhone\FlipMedBack.png 629 | Configs\Default\WinPhone\FlipMedFront.png 630 | FlipSmallBack.png 631 | Configs\Default\WinPhone\FlipSmallFront.png 632 | Configs\Default\WinPhone\FlipWideBack.png 633 | Configs\Default\WinPhone\FlipWideFront.png 634 | 0 635 | 636 | 1 637 | 0 638 | 639 | Configs\Default\WinPhone\ApplicationIcon.png 640 | #000000 641 | 642 | Configs\Default\WinPhone\IconicSmall.png 643 | 644 | 645 | 646 | Configs\Default\WinPhone\IconicWide.png 647 | -1 648 | -1 649 | -1 650 | 1 651 | 0 652 | -1 653 | YourPublisherName 654 | f47823f0-220d-459a-bf68-b6ea984b24a8 655 | -1 656 | 0 657 | -1 658 | -1 659 | -1 660 | -1 661 | 1024 662 | 0 663 | False 664 | #FFFFFF 665 | 0 666 | 667 | 668 | -1 669 | light 670 | -1 671 | "<!-- Insert the languages your title supports here -->","<!-- os_get_language will only return languages that are listed -->","<!-- ""en"" is supported by default -->","<!-- Resource Language=""en-us""/ -->" 672 | 0 673 | 0 674 | 675 | 676 | 677 | 678 | "<mx:Ratings Category=""game"">","<!-- Insert your title ratings here -->","<!-- See ""Title Ratings for Xbox One"" white paper -->","<!-- from developer.xboxlive.com for details -->",</mx:Ratings> 679 | False 680 | False 681 | True 682 | 0 683 | -1 684 | 685 | #FFFFFF 686 | 1024 687 | 688 | 689 | 690 | 691 | -------------------------------------------------------------------------------- /Microtester.project.gmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Configs\Default 5 | 6 | 7 | extensions\js_hiprec_get_timer 8 | 9 | 10 | 11 | sprites\spr_white32 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | fonts\fnt_test 29 | 30 | 31 | objects\obj_tester 32 | objects\obj_blank 33 | 34 | 35 | rooms\rm_test 36 | 37 | 38 | help.rtf 39 | 40 | 41 | 0 42 | 43 | 0 44 | 45 | 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # microtester 2 | A tool for comparing performance of GML scripts. 3 | 4 | # How to use this 5 | 1. Download the repository, open the project file (or import it into GMS2). 6 | 2. Add one or more scripts that you want to compare to the project. 7 | 3. Open `setup_tests_here` and add a `test_add` line for each of them. 8 | 9 | If you need to specify arguments, you can do so by adding them to `test_add`: 10 | 11 | ``` 12 | test_add(scr_add, 1, 2); 13 | ``` 14 | 15 | You can also set custom labels for items by prepending a name argument: 16 | 17 | ``` 18 | test_add("+", scr_add, 1, 2); 19 | ``` 20 | 4. Tweak other settings in the same script if needed. 21 | 5. Run on the platform in question and give it a bit of time to get a good average. 22 | 23 | # Things to consider 24 | * On HTML5, running the game in debug mode and then running a JS profiler can show more accurate results than running microtester alone. 25 | * Be sure to test setups close to your real ones - for example, if you are evaluating whether to substitute a read-only `ds_map` with a `switch` block, use a similar number of items in both to what you would in the actual project. 26 | * Be sure not to optimize prematurely - it can be easy to get caught up on trying to perfect small operations instead of making the actual project. 27 | -------------------------------------------------------------------------------- /extensions/js_hiprec_get_timer.extension.gmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | js_hiprec_get_timer 4 | 1.0.0 5 | 6 | 7 | 04/06/18 8 | Free to use, also for commercial games. 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 29 | 30 | 31 | 32 | 33 | 34 | 35 | jshpgt.gml 36 | extensions\gml.gml 37 | gmcallback_jshpgt 38 | 39 | 2 40 | 0 41 | 42 | 43 | 105554163798254 44 | 45 | 46 | 47 | 48 | 49 | gmcallback_jshpgt 50 | gmcallback_jshpgt 51 | 11 52 | 53 | 2 54 | 0 55 | 56 | 57 | 58 | 59 | 60 | 61 | jshpgt.js 62 | extensions\js.js 63 | 64 | 65 | 5 66 | 0 67 | 68 | 69 | 9223372036854775807 70 | 71 | 72 | 73 | 74 | 75 | jscallback_jshpgt 76 | jscallback_jshpgt 77 | 11 78 | 79 | 2 80 | 2 81 | 82 | 2 83 | 2 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /extensions/js_hiprec_get_timer/jshpgt.gml: -------------------------------------------------------------------------------- 1 | #define gmcallback_jshpgt 2 | /// () 3 | // get_timer() only has ms precision as of 1.4.1804 so we patch it 4 | jscallback_jshpgt(5394, get_timer()); 5 | -------------------------------------------------------------------------------- /extensions/js_hiprec_get_timer/jshpgt.js: -------------------------------------------------------------------------------- 1 | /// 2 | function jscallback_jshpgt(_5394, _get_timer) { 3 | if (performance.now) { 4 | // first we get the JS code of our compiled GML script: 5 | var gmljs = window.gml_Script_gmcallback_jshpgt.toString(); 6 | // then, we parse that JS code to figure out the minified name of get_timer: 7 | var mt = /5394\s*,\s*([$\w]+)/g.exec(gmljs); 8 | if (mt) { 9 | // if all is well, we then replace the implementation with ours: 10 | window[mt[1]] = function() { return performance.now() * 1000000 }; 11 | console.log("jshpgt: Rebound get_timer (" + mt[1] + ")."); 12 | } else console.error("jshpgt: Couldn't find get_timer."); 13 | } else console.error("jshpgt: performance.now is not supported."); 14 | } -------------------------------------------------------------------------------- /fonts/fnt_test.font.gmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | Ubuntu 4 | 12 5 | 0 6 | -1 7 | 0 8 | 1 9 | 3 10 | 0 11 | 12 | 13 | 0 14 | 15 | 16 | 32,127 17 | 956,956 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 | fnt_test.png 120 | 121 | -------------------------------------------------------------------------------- /fonts/fnt_test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameMakerDiscord/microtester/ba8b7463b650b9f792cde6dd26dcc51e33f4e030/fonts/fnt_test.png -------------------------------------------------------------------------------- /objects/obj_blank.object.gmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | <undefined> 4 | 0 5 | -1 6 | 0 7 | 0 8 | <undefined> 9 | <undefined> 10 | 11 | 0 12 | 0 13 | 0 14 | 0.5 15 | 0.100000001490116 16 | 0 17 | 0.100000001490116 18 | 0.100000001490116 19 | 0.200000002980232 20 | -1 21 | 0 22 | 23 | 24 | -------------------------------------------------------------------------------- /objects/obj_tester.object.gmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | <undefined> 4 | 0 5 | -1 6 | 0 7 | 0 8 | <undefined> 9 | <undefined> 10 | 11 | 12 | 13 | 1 14 | 603 15 | 7 16 | 0 17 | 0 18 | -1 19 | 2 20 | 21 | 22 | self 23 | 0 24 | 0 25 | 26 | 27 | 1 28 | tests = ds_list_create(); 29 | test_add(test_blank); 30 | setup_tests_here(); 31 | room_height = ds_list_size(tests) * 32 + 80; 32 | window_set_size(room_width, room_height); 33 | surface_resize(application_surface, room_width, room_height); 34 | swaps = ds_list_create(); 35 | ds_list_copy(swaps, tests); 36 | ntime = 0; 37 | ndone = 0; 38 | if (os_browser == browser_not_a_browser) { 39 | switch (os_type) { 40 | case os_windows: platform = "Windows"; break; 41 | case os_macosx: platform = "Mac OSX"; break; 42 | case os_linux: platform = "Linux"; break; 43 | case os_android: platform = "Android"; break; 44 | case os_ios: platform = "iOS"; break; 45 | default: platform = "???"; break; 46 | } 47 | if (code_is_compiled()) { 48 | platform += " YYC"; 49 | } else platform += " VM"; 50 | } else platform = "HTML5"; 51 | platform += " " + GM_runtime_version; 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 1 60 | 603 61 | 7 62 | 0 63 | 0 64 | -1 65 | 2 66 | 67 | 68 | self 69 | 0 70 | 0 71 | 72 | 73 | 1 74 | test_update(); 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 1 83 | 603 84 | 7 85 | 0 86 | 0 87 | -1 88 | 2 89 | 90 | 91 | self 92 | 0 93 | 0 94 | 95 | 96 | 1 97 | draw_set_font(fnt_test); 98 | var c = $806050; 99 | draw_set_color(c); 100 | var qx = 100; 101 | var qy = 4; 102 | var qw = 400; 103 | var qh = 20; // bar width 104 | var qs = 32; // spacing 105 | var n = ds_list_size(tests); 106 | if (n <= 1) exit; 107 | 108 | // test #0 is blank and used as reference point so that we don't 109 | // count up time that it takes to just do a script call alone 110 | var q, qt, qr, rt, i; 111 | q = tests[|0]; 112 | rt = q[test_t.avg]; 113 | if (include_call_time) rt = 0; 114 | 115 | // draw header: 116 | draw_set_halign(fa_right); 117 | draw_text(qx - 4, qy, "Avg (μs)"); 118 | draw_set_halign(fa_center); 119 | draw_text(qx + qw div 2, qy, "Relative performance"); 120 | draw_set_halign(fa_left); 121 | draw_text(qx + qw + 4, qy, "Name"); 122 | qy += 24; 123 | 124 | // compute minimum/maximum times: 125 | q = tests[|1]; 126 | qt = q[test_t.avg] - rt; 127 | var tmin = qt, tmax = qt; 128 | for (i = 2; i < n; i++) { 129 | q = tests[|i]; 130 | qt = q[test_t.avg] - rt; 131 | tmin = min(tmin, qt); 132 | tmax = max(tmax, qt); 133 | } 134 | tmin = max(tmin, 0); 135 | 136 | // draw rows: 137 | for (i = 1; i < n; i++) { 138 | q = tests[|i]; 139 | qt = q[test_t.avg] - rt; 140 | draw_set_halign(fa_right); 141 | draw_text(qx - 4, qy, string_format(qt, 0, 3)); 142 | draw_set_halign(fa_left); 143 | // 144 | if (i > 0) { 145 | qr = max(0, tmin / qt); 146 | } else qr = 1; 147 | draw_sprite_ext(spr_white32, 0, qx, qy, qw / 32, qh / 32, 0, c, 0.1); 148 | draw_sprite_ext(spr_white32, 0, qx, qy, qr * qw / 32, qh / 32, 0, c, 1); 149 | // 150 | draw_text(qx + 5, qy + 1, string_format(qr * 100, 0, 1) + "%"); 151 | draw_set_color(c_white); 152 | draw_text(qx + 4, qy, string_format(qr * 100, 0, 1) + "%"); 153 | draw_set_color(c); 154 | // 155 | draw_set_valign(fa_middle); 156 | draw_text(qx + qw + 4, qy + qh div 2, q[test_t.name]); 157 | draw_set_valign(fa_top); 158 | qy += qs; 159 | } 160 | 161 | // draw footer: 162 | draw_set_halign(fa_right); 163 | draw_text(qx - 4, qy, string_format_exp(ndone) 164 | + "#" + string_format_exp(ndone * tests_per_frame * calls_per_test)); 165 | draw_set_halign(fa_left); 166 | draw_text(qx, qy, "Tests#Iterations#" + platform); 167 | 168 | 169 | 170 | 171 | 172 | 173 | 0 174 | 0 175 | 0 176 | 0.5 177 | 0.100000001490116 178 | 0 179 | 0.100000001490116 180 | 0.100000001490116 181 | 0.200000002980232 182 | -1 183 | 0 184 | 185 | 186 | -------------------------------------------------------------------------------- /rooms/rm_test.room.gmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 720 5 | 384 6 | 32 7 | 32 8 | 0 9 | 30 10 | 0 11 | 15655112 12 | -1 13 | 14 | 0 15 | -1 16 | -1 17 | 18 | -1 19 | 870 20 | 722 21 | -1 22 | -1 23 | -1 24 | -1 25 | -1 26 | 0 27 | 0 28 | -1 29 | 0 30 | -64 31 | -42 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 | 0 58 | 0 59 | 0 60 | 1024 61 | 768 62 | 0 63 | 10 64 | 0.100000001490116 65 | 66 | -------------------------------------------------------------------------------- /scripts/assert.gml: -------------------------------------------------------------------------------- 1 | /// assert(value, expected_value) 2 | var a = argument0, b = argument1; 3 | if (a != b) show_error("Assertion failed" 4 | + chr(13) + chr(10) + "Received: " + string(a) 5 | + chr(13) + chr(10) + "Expected: " + string(b) 6 | , true); 7 | -------------------------------------------------------------------------------- /scripts/pack.gml: -------------------------------------------------------------------------------- 1 | /// pack(...values)->array 2 | var n = argument_count; 3 | var r = array_create(n); 4 | for (var i = 0; i < n; i++) { 5 | r[i] = argument[i]; 6 | } 7 | return r; 8 | -------------------------------------------------------------------------------- /scripts/setup_tests_here.gml: -------------------------------------------------------------------------------- 1 | #define setup_tests_here 2 | tests_per_frame = 100; // how many times to shuffle & run tests per frame 3 | calls_per_test = 100; // prefer to keep at 1 outside of overly small operations 4 | frames_between_tests = 1; // delay between running tests, in case it's needed 5 | include_call_time = 0; // whether to include script call time in calculations 6 | // 7 | some = 1; 8 | test_add("direct read", n_get); 9 | test_add("direct write", n_set); 10 | test_add("variable_instance_get", vi_get); 11 | test_add("variable_instance_set", vi_set); 12 | test_add("variable_instance_exists", vi_exists); 13 | 14 | #define n_get 15 | return some; 16 | 17 | #define n_set 18 | some = 1; 19 | 20 | #define vi_get 21 | return variable_instance_get(self, "some"); 22 | 23 | #define vi_set 24 | variable_instance_set(self, "some", 1); 25 | 26 | #define vi_exists 27 | return variable_instance_exists(self, "some") -------------------------------------------------------------------------------- /scripts/string_format_exp.gml: -------------------------------------------------------------------------------- 1 | /// string_format_exp(number) 2 | /// @author YellowAfterlife 3 | var i = round(argument0); 4 | var u = ""; 5 | if (i >= 10000) { 6 | i /= 1000; 7 | u = "K"; 8 | if (i >= 10000) { 9 | i /= 1000; 10 | u = "M"; 11 | if (i >= 10000) { 12 | i /= 1000; 13 | u = "B"; 14 | if (i >= 10000) { 15 | i /= 1000; 16 | u = "T"; 17 | } 18 | } 19 | } 20 | return string_format(i, 0, 1) + u; 21 | } else return string(i); 22 | -------------------------------------------------------------------------------- /scripts/test_add.gml: -------------------------------------------------------------------------------- 1 | /// test_add([optional name;]script, ...args) 2 | /// @author YellowAfterlife 3 | // Sets up a script to be tested. 4 | // Will be called with provided arguments. 5 | enum test_t { name, args, total, avg, sizeof } 6 | // handle (script, ...) vs (name, script, ...) 7 | var q = array_create(test_t.sizeof); 8 | var r, k = 0; 9 | var v = argument[0]; 10 | if (is_string(v)) { 11 | q[test_t.name] = v; 12 | r[0] = argument[++k]; 13 | } else { 14 | q[test_t.name] = script_get_name(v); 15 | r[0] = v; 16 | } 17 | // 18 | var n = argument_count; 19 | for (var i = k + 1; i < n; i++) { 20 | r[i - k] = argument[i]; 21 | } 22 | q[test_t.args] = r; 23 | q[test_t.total] = 0; 24 | q[test_t.avg] = 0; 25 | ds_list_add(tests, q); 26 | 27 | -------------------------------------------------------------------------------- /scripts/test_blank.gml: -------------------------------------------------------------------------------- 1 | // intentionally left blank 2 | 3 | -------------------------------------------------------------------------------- /scripts/test_update.gml: -------------------------------------------------------------------------------- 1 | if (++ntime <= frames_between_tests) exit; 2 | ntime = 0; 3 | ndone += 1; 4 | var n = ds_list_size(swaps); 5 | var i, q; 6 | var cpt = calls_per_test; 7 | var tpf = tests_per_frame; 8 | repeat (tests_per_frame) { 9 | // each iteration we shuffle the list 10 | // (to reduce odds of data being impacted by caching on YYC) 11 | // and run the scripts in it while counting up time it took to do so 12 | ds_list_shuffle(swaps); 13 | for (i = 0; i < n; i++) { 14 | q = swaps[|i]; 15 | var w = q[test_t.args], t; 16 | var w0 = w[0], w1, w2, w3, w4, w5, w6, w7; 17 | switch (array_length_1d(w)) { 18 | case 1: 19 | t = get_timer(); 20 | repeat (cpt) script_execute(w0); 21 | break; 22 | case 2: 23 | w1 = w[1]; 24 | t = get_timer(); 25 | repeat (cpt) script_execute(w0, w1); 26 | break; 27 | case 3: 28 | w1 = w[1]; w2 = w[2]; 29 | t = get_timer(); 30 | repeat (cpt) script_execute(w0, w1, w2); 31 | break; 32 | case 4: 33 | w1 = w[1]; w2 = w[2]; w3 = w[3]; 34 | t = get_timer(); 35 | repeat (cpt) script_execute(w0, w1, w2, w3); 36 | break; 37 | case 5: 38 | w1 = w[1]; w2 = w[2]; w3 = w[3]; w4 = w[4]; 39 | t = get_timer(); 40 | repeat (cpt) script_execute(w0, w1, w2, w3, w4); 41 | break; 42 | case 6: 43 | w1 = w[1]; w2 = w[2]; w3 = w[3]; w4 = w[4]; w5 = w[5]; 44 | t = get_timer(); 45 | repeat (cpt) script_execute(w0, w1, w2, w3, w4, w5); 46 | break; 47 | case 7: 48 | w1 = w[1]; w2 = w[2]; w3 = w[3]; w4 = w[4]; w5 = w[5]; w6 = w[6]; 49 | t = get_timer(); 50 | repeat (cpt) script_execute(w0, w1, w2, w3, w4, w5, w6); 51 | break; 52 | default: show_error("Too many arguments", 1); 53 | } 54 | t = get_timer() - t; 55 | q[@test_t.total] += t; 56 | } 57 | } 58 | // then we recalculate the average time per script: 59 | var num_total = ndone * cpt * tpf; 60 | for (i = 0; i < n; i++) { 61 | q = swaps[|i]; 62 | q[@test_t.avg] = q[test_t.total] / num_total; 63 | } 64 | -------------------------------------------------------------------------------- /scripts/trace.gml: -------------------------------------------------------------------------------- 1 | /// trace(...values) 2 | var r = "", i = -1, s; 3 | repeat (argument_count) r += string(argument[++i]) + " "; 4 | show_debug_message(r); 5 | -------------------------------------------------------------------------------- /sprites/images/spr_white32_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameMakerDiscord/microtester/ba8b7463b650b9f792cde6dd26dcc51e33f4e030/sprites/images/spr_white32_0.png -------------------------------------------------------------------------------- /sprites/spr_white32.sprite.gmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 0 4 | 0 5 | 0 6 | 1 7 | 0 8 | 0 9 | 0 10 | 0 11 | 31 12 | 0 13 | 31 14 | 0 15 | 0 16 | 17 | 0 18 | 19 | 0 20 | 32 21 | 32 22 | 23 | images\spr_white32_0.png 24 | 25 | 26 | --------------------------------------------------------------------------------