Commit 608085c
zap.Any: Reduce stack size with generics (#1310)
Yet another attempt at reducing the stack size of zap.Any,
borrowing from #1301, #1303, #1304, #1305, #1307, and #1308.
This approach defines a generic data type for field constructors
of a specific type. This is similar to the lookup map in #1307,
minus the map lookup, the interface match, or reflection.
type anyFieldC[T any] func(string, T) Field
The generic data type provides a non-generic method
matching the interface:
interface{ Any(string, any) Field }
**Stack size**:
The stack size of zap.Any following this change is 0xc0 (192 bytes).
% go build -gcflags -S 2>&1 | grep ^go.uber.org/zap.Any
go.uber.org/zap.Any STEXT size=5861 args=0x20 locals=0xc0 funcid=0x0 align=0x0
This is just 8 bytes more than #1305,
which is the smallest stack size of all other attempts.
**Allocations**:
Everything appears to get inlined with no heap escapes:
% go build -gcflags -m 2>&1 |
grep field.go |
perl -n -e 'next unless m{^./field.go:(\d+)}; print if ($1 >= 413)' |
grep 'escapes'
[no output]
(Line 413 declares anyFieldC)
Besides that, the output of `-m` for the relevant section of code
consists of almost entirely:
./field.go:415:6: can inline anyFieldC[go.shape.bool].Any
./field.go:415:6: can inline anyFieldC[go.shape.[]bool].Any
./field.go:415:6: can inline anyFieldC[go.shape.complex128].Any
[...]
./field.go:415:6: inlining call to anyFieldC[go.shape.complex128].Any
./field.go:415:6: inlining call to anyFieldC[go.shape.[]bool].Any
./field.go:415:6: inlining call to anyFieldC[go.shape.bool].Any
Followed by:
./field.go:428:10: leaking param: key
./field.go:428:22: leaking param: value
**Maintainability**:
Unlike some of the other approaches, this variant is more maintainable.
The `zap.Any` function looks roughly the same.
Adding new branches there is obvious, and requires no duplication.
**Performance**:
This is a net improvement against master on BenchmarkAny's
log-go checks that log inside a new goroutine.
```
name old time/op new time/op delta
Any/string/field-only/typed 25.2ns ± 1% 25.6ns ± 2% ~ (p=0.460 n=5+5)
Any/string/field-only/any 56.9ns ± 3% 79.4ns ± 0% +39.55% (p=0.008 n=5+5)
Any/string/log/typed 1.47µs ± 0% 1.49µs ± 4% +1.58% (p=0.016 n=4+5)
Any/string/log/any 1.53µs ± 2% 1.55µs ± 1% +1.37% (p=0.016 n=5+5)
Any/string/log-go/typed 5.97µs ± 6% 5.99µs ± 1% ~ (p=0.151 n=5+5)
Any/string/log-go/any 10.9µs ± 0% 6.2µs ± 0% -43.32% (p=0.008 n=5+5)
Any/stringer/field-only/typed 25.3ns ± 1% 25.5ns ± 1% +1.09% (p=0.008 n=5+5)
Any/stringer/field-only/any 85.5ns ± 1% 124.5ns ± 0% +45.66% (p=0.008 n=5+5)
Any/stringer/log/typed 1.43µs ± 1% 1.42µs ± 2% ~ (p=0.175 n=4+5)
Any/stringer/log/any 1.50µs ± 1% 1.56µs ± 6% +4.20% (p=0.008 n=5+5)
Any/stringer/log-go/typed 5.94µs ± 0% 5.92µs ± 0% -0.40% (p=0.032 n=5+5)
Any/stringer/log-go/any 11.1µs ± 2% 6.3µs ± 0% -42.93% (p=0.008 n=5+5)
name old alloc/op new alloc/op delta
Any/string/field-only/typed 0.00B 0.00B ~ (all equal)
Any/string/field-only/any 0.00B 0.00B ~ (all equal)
Any/string/log/typed 64.0B ± 0% 64.0B ± 0% ~ (all equal)
Any/string/log/any 64.0B ± 0% 64.0B ± 0% ~ (all equal)
Any/string/log-go/typed 112B ± 0% 112B ± 0% ~ (all equal)
Any/string/log-go/any 128B ± 0% 128B ± 0% ~ (all equal)
Any/stringer/field-only/typed 0.00B 0.00B ~ (all equal)
Any/stringer/field-only/any 0.00B 0.00B ~ (all equal)
Any/stringer/log/typed 64.0B ± 0% 64.0B ± 0% ~ (all equal)
Any/stringer/log/any 64.0B ± 0% 64.0B ± 0% ~ (all equal)
Any/stringer/log-go/typed 112B ± 0% 112B ± 0% ~ (all equal)
Any/stringer/log-go/any 128B ± 0% 128B ± 0% ~ (all equal)
name old allocs/op new allocs/op delta
Any/string/field-only/typed 0.00 0.00 ~ (all equal)
Any/string/field-only/any 0.00 0.00 ~ (all equal)
Any/string/log/typed 1.00 ± 0% 1.00 ± 0% ~ (all equal)
Any/string/log/any 1.00 ± 0% 1.00 ± 0% ~ (all equal)
Any/string/log-go/typed 3.00 ± 0% 3.00 ± 0% ~ (all equal)
Any/string/log-go/any 3.00 ± 0% 3.00 ± 0% ~ (all equal)
Any/stringer/field-only/typed 0.00 0.00 ~ (all equal)
Any/stringer/field-only/any 0.00 0.00 ~ (all equal)
Any/stringer/log/typed 1.00 ± 0% 1.00 ± 0% ~ (all equal)
Any/stringer/log/any 1.00 ± 0% 1.00 ± 0% ~ (all equal)
Any/stringer/log-go/typed 3.00 ± 0% 3.00 ± 0% ~ (all equal)
Any/stringer/log-go/any 3.00 ± 0% 3.00 ± 0% ~ (all equal)
```
It causes a regression in "field-only"
which calls the field constructor and discards the result
without using it in a logger.
I believe this is acceptable because that's not a real use case;
we expect the result to be used with a logger.1 parent cd2f6ac commit 608085c
1 file changed
+105
-64
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
410 | 410 | | |
411 | 411 | | |
412 | 412 | | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
413 | 450 | | |
414 | 451 | | |
415 | 452 | | |
| |||
418 | 455 | | |
419 | 456 | | |
420 | 457 | | |
421 | | - | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
422 | 461 | | |
423 | | - | |
| 462 | + | |
424 | 463 | | |
425 | | - | |
| 464 | + | |
426 | 465 | | |
427 | | - | |
| 466 | + | |
428 | 467 | | |
429 | | - | |
| 468 | + | |
430 | 469 | | |
431 | | - | |
| 470 | + | |
432 | 471 | | |
433 | | - | |
| 472 | + | |
434 | 473 | | |
435 | | - | |
| 474 | + | |
436 | 475 | | |
437 | | - | |
| 476 | + | |
438 | 477 | | |
439 | | - | |
| 478 | + | |
440 | 479 | | |
441 | | - | |
| 480 | + | |
442 | 481 | | |
443 | | - | |
| 482 | + | |
444 | 483 | | |
445 | | - | |
| 484 | + | |
446 | 485 | | |
447 | | - | |
| 486 | + | |
448 | 487 | | |
449 | | - | |
| 488 | + | |
450 | 489 | | |
451 | | - | |
| 490 | + | |
452 | 491 | | |
453 | | - | |
| 492 | + | |
454 | 493 | | |
455 | | - | |
| 494 | + | |
456 | 495 | | |
457 | | - | |
| 496 | + | |
458 | 497 | | |
459 | | - | |
| 498 | + | |
460 | 499 | | |
461 | | - | |
| 500 | + | |
462 | 501 | | |
463 | | - | |
| 502 | + | |
464 | 503 | | |
465 | | - | |
| 504 | + | |
466 | 505 | | |
467 | | - | |
| 506 | + | |
468 | 507 | | |
469 | | - | |
| 508 | + | |
470 | 509 | | |
471 | | - | |
| 510 | + | |
472 | 511 | | |
473 | | - | |
| 512 | + | |
474 | 513 | | |
475 | | - | |
| 514 | + | |
476 | 515 | | |
477 | | - | |
| 516 | + | |
478 | 517 | | |
479 | | - | |
| 518 | + | |
480 | 519 | | |
481 | | - | |
| 520 | + | |
482 | 521 | | |
483 | | - | |
| 522 | + | |
484 | 523 | | |
485 | | - | |
| 524 | + | |
486 | 525 | | |
487 | | - | |
| 526 | + | |
488 | 527 | | |
489 | | - | |
| 528 | + | |
490 | 529 | | |
491 | | - | |
| 530 | + | |
492 | 531 | | |
493 | | - | |
| 532 | + | |
494 | 533 | | |
495 | | - | |
| 534 | + | |
496 | 535 | | |
497 | | - | |
| 536 | + | |
498 | 537 | | |
499 | | - | |
| 538 | + | |
500 | 539 | | |
501 | | - | |
| 540 | + | |
502 | 541 | | |
503 | | - | |
| 542 | + | |
504 | 543 | | |
505 | | - | |
| 544 | + | |
506 | 545 | | |
507 | | - | |
| 546 | + | |
508 | 547 | | |
509 | | - | |
| 548 | + | |
510 | 549 | | |
511 | | - | |
| 550 | + | |
512 | 551 | | |
513 | | - | |
| 552 | + | |
514 | 553 | | |
515 | | - | |
| 554 | + | |
516 | 555 | | |
517 | | - | |
| 556 | + | |
518 | 557 | | |
519 | | - | |
| 558 | + | |
520 | 559 | | |
521 | | - | |
| 560 | + | |
522 | 561 | | |
523 | | - | |
| 562 | + | |
524 | 563 | | |
525 | | - | |
| 564 | + | |
526 | 565 | | |
527 | | - | |
| 566 | + | |
528 | 567 | | |
529 | | - | |
| 568 | + | |
530 | 569 | | |
531 | | - | |
| 570 | + | |
532 | 571 | | |
533 | | - | |
| 572 | + | |
534 | 573 | | |
535 | | - | |
| 574 | + | |
536 | 575 | | |
537 | | - | |
| 576 | + | |
538 | 577 | | |
539 | | - | |
| 578 | + | |
540 | 579 | | |
541 | | - | |
| 580 | + | |
542 | 581 | | |
543 | | - | |
| 582 | + | |
544 | 583 | | |
545 | | - | |
| 584 | + | |
546 | 585 | | |
547 | | - | |
| 586 | + | |
548 | 587 | | |
| 588 | + | |
| 589 | + | |
549 | 590 | | |
0 commit comments