[Question]
  [
There has been a question about [yes](https://codegolf.stackexchange.com/questions/42428/yes-is-91-lines-long) in the past, but this one is slightly different. You see, despite `yes` having a rather long size, it is incredibly fast. Running the following command:
```
timeout 1s yes > out
```
yields a file that is **1.9 GB**. Compared to this program:
```
int puts();main(){while(1){puts("y");}}
```
which yields a measly 150 Mb.
The goal is to write a program that outputs `y\n` (that's `y` with a newline) repeatedly forever, in as few lines as possible, outputting the biggest size file in as short time as possible. 
The scoring works with the equation: `b * y/y'`. The value `b` is the size of your program in bytes. The value of `y` is the size in bytes of the `out` file after running the following command: `timeout 1s yes > out`. The value of `y'` is the size in bytes of the `out` file after running the following command: `timeout 1s PROG > out` where `PROG` is your program, eg. `./a.out`. Your program should match the output of the gnu coreutils program `yes` ran with no arguments exactly, albeit outputting `y` at any speed you like. Outputting zero bytes would be a divide by zero in the original equation, resulting in a score of inf for these purposes. 
Lowest score wins.
Edit:
I will run all code on my computer, please show compilation commands and any setup required.
Specs (in case you want to optimize or something):
* OS: Arch Linux 5.5.2-arch1-1
* CPU: AMD Ryzen 2600X
* SSD: Samsung 970 EVO NVMe
* RAM: 16GB 3200MHz
Here is a script to calculate the score, since it seems people are having trouble:
```
b=$(wc -c < $1)
timeout 1s yes > out
y=$(wc -c < out)
timeout 1s $2 > out
y2=$(wc -c < out)
rm out
echo "scale=3;$b*$y/$y2" | bc
```
Example, given that the script is called `score.sh` and your program is `yes.py`:
```
./score.sh yes.py "python yes.py"
```
  
[Answer]
# C, 112 bytes, 28 TB/s, score ‚âà 0.008
```
long b[9<<21];main(){for(b[2]=write(*b=1,wmemset(b+8,'\ny\ny',1<<25),1<<27)/2;b[3]=b[2]*=2;ioctl(1,'@ ”\r',b));}
```
(If you‚Äôre having trouble copying and pasting this, replace the multicharacter constant `'@ ”\r'` with `'@ \x94\r'` or `1075876877`.)
This writes 128 MiB of `y\n`s to stdout, and then repeatedly invokes the [`FICLONERANGE`](http://man7.org/linux/man-pages/man2/ioctl_ficlonerange.2.html) `ioctl` to double the file‚Äôs length by adding new references to the same disk blocks. Requires Linux x86-64 and a filesystem supporting `FICLONERANGE`, such as Btrfs or XFS; stdout must be opened in read-write mode (e.g. `./prog 1<> out` in bash).
### Self-contained testing script
This script loop-mounts a freshly created filesystem from a memory-backed image file and runs the program there. (I get about 43 TB/s in-memory, but the ratio with `yes(1)` is similar.) It works with either Btrfs or XFS, but Btrfs seems to give better scores.
```
#!/usr/bin/env bash
set -eux
dir="$(mktemp -dp /dev/shm)"
cd "$dir"
trap 'umount fs || true; rm -r "$dir"' EXIT
printf "long b[9<<21];main(){for(b[2]=write(*b=1,wmemset(b+8,'\\\\ny\\\\ny',1<<25),1<<27)/2;b[3]=b[2]*=2;ioctl(1,'@ \\x94\\\\r',b));}" > prog.c
b="$(stat -c %s prog.c)"
gcc -O3 prog.c -o prog
dd of=fs.img bs=1 count=0 seek=8G
# Pick one:
mkfs.btrfs fs.img
#mkfs.xfs -m reflink=1 fs.img
mkdir fs
mount fs.img fs
sync
timeout 1 yes 1<> fs/out || true
y="$(stat -c %s fs/out)"
rm fs/out
sync
timeout 1 ./prog 1<> fs/out || true
y1="$(stat -c %s fs/out)"
echo "score = $b * $y / $y1 = $(bc -l <<< "$b * $y / $y1")"
```
[Answer]
# [Bash](https://www.gnu.org/software/bash/), 3 bytes, 1.9 GB/s
```
yes
```
[Try it online!](https://tio.run/##S0oszvj/vzK1@P9/AA "Bash ‚Äì Try It Online")
Admittedly this is a troll solution, but the rules do not explicitly forbid it, and it should get you a value close to 3, which is not bad.
[Answer]
# x86-64 machine code (Linux system calls), 29B \* 4.7GB/6.6GB = ~20.6 on tmpfs on Skylake
(Or even 28 bytes, but I haven't benchmarked Noah's suggestion of using the low 16 bits of the address as the count for `rep stosd`. Asm source for it [on Godbolt](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:%271%27,fontScale:14,fontUsePx:%270%27,j:1,lang:assembly,selection:(endColumn:4,endLineNumber:19,positionColumn:4,positionLineNumber:19,selectionStartColumn:4,selectionStartLineNumber:17,startColumn:4,startLineNumber:17),source:%27%3B+test+with%0A%3B+sudo+mount+-t+tmpfs+-o+size%3D1G,huge%3Dalways+tmpfs+/tmp/testd%0A%3B+asm-link+-nd+yes.asm+%26%26%0A%3B+./yes+%3E+testd/yesout+%26%26+perf+stat+-d+./yes+%3E+testd/yesout+++++++%23+warmup+and+run%0A%0Aglobal+_start%0A_start:%0A%3B%3B+All+regs+zeroed+at+the+top+of+a+static+executable+(except+RSP)%0A%0ASIZEPOW+equ+17%0A%3B+++mov++ecx,+8192%0A%3B+++bts++ecx,+16++++++%3B+1%3C%3C16+%3D+65536+x+4+bytes+to+fill.++4+bytes,+any+power+of+2+vs.+mov+cx,+imm16+limited+to+65535%0A%3B+++bts++ecx,+SIZEPOW%0A%3B+++mov++edx,+ecx++++++%3B+size+arg+for+sys_write+in+bytes%3B+1/4+of+the+actual+buffer+size%0A%0A+++mov++eax,+%60y%5Cny%5Cn%60%0A+++mov++edi,+buf%0A+++mov++cx,+di+++++++%3B+We+align+%60buf%60+s.t+its+lower+2-bytes+will+be+(65536+-+16384)+which+is+both+leaves+the+write%0A+++++++++++++++++++++%3B+buf+page+aligned+(for+perf)+and+can+be+used+to+set+buffer+size+(saving+1-byte)%0A+++mov++edx,+ecx+++++%3B+size+arg+for+sys_write+in+bytes%3B+1/4+of+the+actual+buffer+size%0A+++mov++esi,+edi%0A+++%3Bshr++ecx,+2++++++%3B+just+fill+4x+as+much+memory+as+needed%0A+++rep++stosd++++++++%3B+wmemset(rdi,+eax,+rcx)++4*rcx+bytes%0A+++%0A+++lea+++edi,+%5Brcx+%2B+1%5D+++%3B+++mov++edi,+1%0A.loop:%0A+++mov++eax,+edi+++++%3B+__NR_write+%3D+stdout+fileno%0A+++syscall+++++++++++%3B+sys_write(1+/*EDI*/,+buf+/*RSI*/,+1%3C%3CSIZEPOW+/*RDX*/)%0A%25if+0%0A+++jmp++.loop%0A%25else%0A+++test+eax,eax++++++%3B%3B%3B%3B%3B%3B%3B%3B%3B%3B%3B+For+benchmarking+purposes:+abort+on+write+fail%0A+++jge++.loop%0A%0A+++mov+eax,+231++++++%3B+not+golfed%0A+++xor+edi,+edi%0A+++syscall+++++++++++%3B+sys_exit_group(0)%0A%25endif%0A%0Asection+.bss%0A+align+65536%0A+unused+:+resd+65536+-+16384%0A+buf:+resd+(65536+-+16384)+*+4%0A%27),l:%275%27,n:%270%27,o:%27Assembly+source+%231%27,t:%270%27)),k:33.07575924940335,l:%274%27,m:100,n:%270%27,o:%27%27,s:0,t:%270%27),(g:!((h:compiler,i:(compiler:nasm21402,deviceViewOpen:%271%27,filters:(b:%270%27,binary:%271%27,binaryObject:%271%27,commentOnly:%270%27,demangle:%270%27,directives:%270%27,execute:%270%27,intel:%270%27,libraryCode:%270%27,trim:%271%27),flagsViewOpen:%271%27,fontScale:14,fontUsePx:%270%27,j:1,lang:assembly,libs:!(),options:%27-felf64%27,selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:%275%27,n:%270%27,o:%27+NASM+2.14.02+(Editor+%231)%27,t:%270%27)),k:33.59090741726333,l:%274%27,m:49.86033519553072,n:%270%27,o:%27%27,s:0,t:%270%27),(g:!((h:llvmOptPipelineView,i:(%27-fno-discard-value-names%27:%270%27,compilerName:%27llc+(trunk)%27,demangle-symbols:%270%27,dump-full-module:%271%27,editorid:1,filter-debug-info:%270%27,filter-inconsequential-passes:%271%27,filter-instruction-metadata:%270%27,fontScale:14,fontUsePx:%270%27,j:1,selectedFunction:foo,selectedIndex:10,sidebarWidth:250,treeid:0),l:%275%27,n:%270%27,o:%27LLVM+Opt+Pipeline+Viewer+NASM+2.14.02+(Editor+%231,+Compiler+%231)%27,t:%270%27)),k:33.33333333333333,l:%274%27,n:%270%27,o:%27%27,s:0,t:%270%27)),l:%272%27,n:%270%27,o:%27%27,t:%270%27)),version:4).)
At about 6.6 GiB/s, this runs faster than GNU `yes` on [tmpfs](https://en.wikipedia.org/wiki/Tmpfs), the widely-used Linux ramdisk-like filesystem backed by the pagecache. I made sure to align my buffer to at least a cache-line boundary (and in fact a 4k page boundary) so the kernel's `copy_from_user` memcpy-like function using `rep movsb` would be most efficient.
**I don't expect this will outperform `yes` writing to an SSD on a fast Ryzen CPU which isn't the bottleneck; posted score is tentative.** However, writing 2 or 4 bytes at a time is unusably slow so we need a buffer to avoid a huge score penalty (like a factor of 2000 on tmpfs!). But probably this will score about 29 running at the same speed as GNU `yes` if they both fill the page-cache to max capacity with dirty pages and max out I/O bandwidth during the 1s window.
It's break-even for code size to use a buffer in the BSS instead of reserving stack space, in a Linux position-dependent executable where a static address can be put in a register with 5-byte `mov r32, imm32`. Using more space in the BSS doesn't increase the size of an executable that already has a BSS section/segment. But in this case it does make the executable larger so I'm not totally sure it's justified to not count anything for executable metadata for the BSS. **But as usual, I'm counting only the size of the `.text` section.** (And there's no initialized static data; all the constants are immediate.)
Without aligning the stack by 64 or 4k, `sub esp, edx`; `mov edi, esp` would be only 4 bytes, and safe in a Linux x32 executable: 32-bit pointers in 64-bit mode. (For efficient `syscall` instead of slow `int 0x80` or cumbersome `sysenter` in 32-bit mode). Otherwise break-even for `sub rsp, rdx`. So if not counting the BSS bothers you, save a byte and use the stack for buffers up to almost 8MiB (with default `ulimit -s`).
We fill a buffer that's 4x larger than we actually pass to write; `rep stosd` needs a repeat count of dword chunks and it's convenient to use the same number as a byte count for the system call.
[Try it online!](https://tio.run/##dVPvb9owEP3uv@JJUyvKCjSUshXKpEndpn7ZqvbDpv0QdZJLcOvEme0U6D/PziGMVtoiIuM733vv3jnSOSpive6V0hWbzRSenMdS@YWYwtWpQWHq0qPn4Ysqc@gZOPVEs@jT8aLOaSb1Uq5dmxzwMggIKVczYE@r8gG9MsWaXJ8DODzkTH/AW7xruNLw39SeM6jIZnBeMl3670Pb5xWW0hZ1BcnIti6FyLWJpcaci60X22UiplO81xqWcocnsoZSMLZfELypYDLIhk0loBUltZexJnRolVDlcXN7fSTE7dX3D9dfvoJ@14jesHawIY8AJatjvI3Oh00o9q4NReOtxCmiiwvezDA@OzsdY4UR4jX3wtTIlNZ97CLH3MYalVmSDZqGeHT9hiTgqaJgFK0K5Vk91wa4M/GCs9Uo/mpLOciZnZIwL0ibIzMWbu3mS8toUOWWn6UORoE5GCMTX7ORcZ1lLCdUij2uZNy79c@Sf3fP2NRxOL8POA5wNASmbmFblcOdnPuab1iwAKMVXxIUdbJAQYWx67AtiVJKQ7GlCjwg49J27ly85IOOfMcG1kaQTVZH7GWX120/oTS8miRaeT9C8jWiXw3Gc@GR6GtjqsnLJjnV8s3nn29av2asJQ2XkLVTaUIFm5lIbmT/TPcGdyIMuh8ur7qDxh/e3Nw2G74Zu2vFsctv3cGROFAZTgLkfcFNN5rEAWlHIdZ8k0EYvy3N/sFHnmpMZbIopH1QZY6qtpVx5CaQsbEepsS2g0wq3XDktOPY9d20PTyNdl2UxiM3OttOYsUUjV3tWP/XN62Un@fW1FXnhHuiMlWZEI4Sr1hEP3Y8HKlVXmJ0cj4WwZYJj5kHvPdEbDZ/AA "Assembly (nasm, x64, Linux) ‚Äì Try It Online") (NASM source which assembles to this answer's machine code.) It works on TIO; it doesn't depend on the output being a regular file or anything. Below is a NASM listing of machine code hexdump & source.
```
 6                                  global _start
 7                                  _start:
 8                                  ;; All regs zeroed at the top of a Linux static executable (except RSP)
 9                                  
10                                  SIZEPOW equ 17
13 00000000 0FBAE911                   bts  ecx, SIZEPOW  ; 1<<SIZEPOW x 4 bytes to fill.
14 00000004 89CA                       mov  edx, ecx      ; size arg for sys_write in bytes; 1/4 of the actual buffer size
15                                  
16 00000006 B8790A790A                 mov  eax, `y\ny\n`
25 0000000B BF[00000000]               mov  edi, buf        ; mov r32, imm32 static address; 00... is before linking
26 00000010 89FE                       mov  esi, edi        ; syscall arg
27                                  
28                                     ;shr  ecx, 2         ; just fill 4x as much memory as needed
29 00000012 F3AB                       rep  stosd           ; wmemset(rdi, eax, rcx)  4*rcx bytes
30                                     
31 00000014 8D7901                     lea   edi, [rcx + 1]  ;   mov  edi, 1
32                                  .loop:
33 00000017 89F8                       mov  eax, edi         ; __NR_write = stdout fileno
34 00000019 0F05                       syscall
36 0000001B EBFA                       jmp  .loop
47                                  section .bss
48                                   align 4096
49 00000000 <res 00080000>           buf: resd 1<<SIZEPOW
```
0x1b + 2 bytes for last instruction is 29 bytes total.
`mov cx, imm16` would also be 4 bytes, same as BTS, but is limited to 0..65535. vs. [BTS r32, imm8](https://www.felixcloutier.com/x86/bts) creating any power of 2. (Both depend on a zeroed RCX to start with, to produce a result zero-extended into RCX for `rep stos`)
`mov ax, `y\n``  would be 4 bytes, 1 fewer than `mov eax, imm32`, but then we'd need `rep stosw` which costs an extra operand-size prefix. This would have kept the ratio of filled buffer to used buffer at 2:1 instead of 4:1, so I should have done that to save a few pagefaults at startup, but not redoing the benchmarking now. (`rep stosw` is still fast on Skylake I think; not sure if Zen+ might suffer; but more than a factor of 2 in fill bandwidth + page fault cost is unlikely.)
A static buffer makes alignment to a cache line (or even the page size) not cost instructions; having the stack only 16-byte aligned was a slowdown. I recorded times in comments on my original code that aligned the stack pointer by 64kiB or not after reserving space for a buffer. Alignment to 64k instead of 16B made a ~3% difference in overall speed for writing a 1GiB file (to tmpfs, exiting on ENOSPC) with SIZEPOW=16, and led to a reduction in instructions retired as well. (Measured with `perf stat ./yes > testd/yesout`)
```
     ;;;; instead of  mov  edi, buf
    sub  rsp, rdx
    ;   and  rsp, -65536   ; With: 631.4M cycles 357.6M insns.   Without:  651.3M cycles 359.4M instructions.  (times are somewhat noisy but there's a real difference)
 ;;  mov  rdi, rsp   ; 3 bytes
    push  rsp
    pop   rdi        ; copy a 64-bit reg in 2 bytes
    push  rsp
    pop   rsi
```
For other benchmarking purposes (with a smaller 1GiB tmpfs), it was convenient to use **a loop that exited when `write()` failed** (with `-ENOSPC`) instead of looping until killed. I used this as the bottom of the loop
```
35                                  %if 0
36 0000001B EBFA                       jmp  .loop
37                                  %else
38                                     test eax,eax      ;;;;;;;;;;; For benchmarking purposes: abort on write fail
39                                     jge  .loop
40                                  
41                                     mov eax, 231    ; not golfed
42                                     xor edi, edi
43                                     syscall         ; sys_exit_group(0)
44                                  %endif
45                                  
```
---
# Testing
**I tested using tmpfs** because I don't want to wear out my SSD repeatedly testing this. And because keeping up with a consumer-grade SSD is trivial with any reasonable buffer size. **More interesting (to me) is to find the CPU/memory-bound sweet spot between system call overhead from making too many small `write` system calls vs. L2 cache misses** from re-reading too large a buffer every time. And also minimize time spent on filling a buffer before even starting to make system calls. (Although note that with write-behind I/O buffering for filesystems backed by real disk, there's no advantage to using a smaller buffer to get disk-write started sooner. I/O write-back to actual physical media wouldn't start until dirty pages hit the Linux kernel's high water mark. The default dirty *timeout* is 500 centisecs, and powertop suggests raising that to 1500 (15 seconds), so that's not going to come into play, just the high water mark. So what really matters is getting to the high water mark ASAP for a physical disk, and potentially pushing as many dirty pages into the pagecache as possible within the 1 second window, to finish writeback after `yes` dies. So this 1-second test probably depends on how much RAM your machine has (and even how much *free* RAM), if you're using a physical disk instead of tmpfs.)
`write` inside the kernel is basically a `memcpy` from the provided buffer into the pagecache; specifically Linux's `copy_from_user` function which uses `rep movsb` on systems with [ERMSB (Intel since IvB)](https://stackoverflow.com/questions/43343231/enhanced-rep-movsb-for-memcpy) or `rep movsq` when it's fast (PPro and later, including non-Intel vendors.)
**According to `perf record` / `perf report`** output, with a 128k buffer size, **45% of the counts for hardware "cycles" were in `clear_page_erms`** (on `rep stosb`) and then **18.4% in `copy_user_enhanced_fast_string`** on `rep movsb`. (Makes some sense: clearing is touching a cold page, copy is copying over a just-cleared buffer, presumably hitting in L2 cache for src and destination. Or L1d for dst if it clears 4k at a time. Or only L3 cache if it's clearing whole hugepages :/) Next highest was `iov_iter_fault_in_readable` at 3.8%. **But anyway, only ~63% of total CPU time was spent on the "real work" of actually copying into the pagecache.** And that happens inefficiently, zeroing before copying.
I tried with **`tmpfs` with `huge=never`** (which is the default) and **only got 4.8GiB** for 1s with the 128kiB buffer version that gets 6.6GiB on hugepages. So clearly hugepages are worth it overall. perf record counts for `cycles` were: 14%: `clear_page_erms` and 10% `copy_user_enhanced_fast_string`, with many other kernel functions taking low single digits percentages, like `try_charge` at 4%, `__pagevec_lru_add_fn`, `get_mem_cgroup_from_mm`, `__this_cpu_preempt_check`, and `_raw_spin_lock_irq` at 3 to 2%. Managing memory in 4kiB chunks obviously costs a lot more than in 2MiB chunks.
### Test setup
* **i7-6700k @ 3.9GHz** with 0xd6 microcode update (Nov 2019). (quad core [Skylake-client microarchitecture](https://en.wikichip.org/wiki/intel/microarchitectures/skylake_(client)), per-core caches: L1d 32k, L2 256k. Shared L3 = 8MiB) vs. Ryzen having 512kiB L2 caches.  
During this test: `/sys/devices/system/cpu/cpufreq/policy0/energy_performance_preference` = balance\_performance, not full `performance` EPP setting. So this is closer to the normal bootup machine state of balance\_power). I ran a warm-up run right before the main test to make sure the CPU speed was at full before the timed 1-second started: `timeout 1s ./yes > testd/yesout; perf stat -d timeout 1s yes > testd/yesout`.
With EPP at `performance` (max turbo = 4.2GHz, near-instant ramp-up), in practice it runs at 4.1GHz average for the test. I get up to 6.9GiB written instead of 6.6, for the 128k buffer version. (And up to 7.3GiB with the `writev` version.)
* **16 GiB of DDR4-2666** (2x8GB DIMMs, dual channel)
* OS = Arch GNU/Linux, kernel = Linux 5.4.13-arch1-1
* **Filesystem = tmpfs** using transparent hugepages:  
`sudo mount -t tmpfs -o size=10G,huge=always tmpfs /tmp/test`. Much of the file is using transparent hugepages: from /proc/meminfo after writing a 6.4G file: `ShmemHugePages: 6723584 kB` (6566MB), and goes down to `83968 kB` (82MB) after deleting it. **It's using x86-64 2MiB hugepages instead of 4k normal pages to reduce TLB misses.**
* System idle except for Chromium using about 3% of one core at idle clock speed.
* free memory was sufficient for tmpfs not to actually page anything out to swapspace during the test:
```
$ free -m   # show numbers in megabytes.  Test output deleted; tmpfs nearly empty
              total        used        free      shared  buff/cache   available
Mem:    15820        2790       12164         236         864       12497
Swap:    2047         930        1117
$ cat /proc/sys/vm/swappiness 
6
```
* Spectre / Meltdown mitigations (big overhead per system call, above the ~100 cycles each for `syscall` / `sysret` to get in/out of the kernel):
```
$ grep . /sys/devices/system/cpu/vulnerabilities/*
/sys/devices/system/cpu/vulnerabilities/itlb_multihit:KVM: Vulnerable
/sys/devices/system/cpu/vulnerabilities/l1tf:Mitigation: PTE Inversion
/sys/devices/system/cpu/vulnerabilities/mds:Mitigation: Clear CPU buffers; SMT vulnerable
/sys/devices/system/cpu/vulnerabilities/meltdown:Mitigation: PTI
/sys/devices/system/cpu/vulnerabilities/spec_store_bypass:Mitigation: Speculative Store Bypass disabled via prctl and seccomp
/sys/devices/system/cpu/vulnerabilities/spectre_v1:Mitigation: usercopy/swapgs barriers and __user pointer sanitization
/sys/devices/system/cpu/vulnerabilities/spectre_v2:Mitigation: Full generic retpoline, IBPB: conditional, IBRS_FW, STIBP: conditional, RSB filling
/sys/devices/system/cpu/vulnerabilities/tsx_async_abort:Mitigation: Clear CPU buffers; SMT vulnerable
```
### Results writing to tmpfs for 1 second: best case 6.6GiB
Timed with this as a shell one-liner
```
 asm-link -nd yes.asm &&    # assemble with NASM + link
 taskset -c 3 timeout 1s ./yes > testd/yesout;     # warm-up run
 time taskset -c 3  timeout 1s ./yes > testd/yesout;
 ls -lh testd/yesout && rm testd/yesout
```
Up-arrow recall that string of commands a few times, take the best case. (Assume that lower values didn't ramp up the CPU speed right away; spent some time allocating hugepages, or had other spurious interference.)
I intentionally limited myself to only looking at 2 significant figures of file size (letting ls round to `x.y GiB`) because I know there's going to be noise, so perhaps keeping the data simpler might be good.
### Results for various buffer sizes writing to tmpfs: 6.6GiB
(I did see 6.7G in some early testing with SIZEPOW=16 or 17, and I think even 6.8 or 9, but couldn't reproduce it once things settled down. Maybe some lucky early arrangement of hugepages that didn't last into a stable state?)
* SIZEPOW=1, buffer size: 2 (just `'y\n'`), best-case size: 2.9*MiB*  
real 0m1.002s, user 0m0.431s, sys 0m0.570s
* SIZEPOW=2, buffer size: 4, best-case size: 5.8MiB  
real 0m1.002s, user 0m0.381s, sys 0m0.620s
* ...
* SIZEPOW=11, buffer size: 1024, best-case size: 1.3GiB  
real 0m1.005s, user 0m0.343s, sys 0m0.661s
* SIZEPOW=11, buffer size: 2048, best-case size: 2.3GiB  
real 0m1.008s, user 0m0.270s, sys 0m0.737s. (Smaller than 1x 4k page = bad)
* SIZEPOW=12, buffer size: 4096, best-case size: 3.6GiB  
real 0m1.012s, user 0m0.237s, sys 0m0.772s
* SIZEPOW=13, buffer size: 8192 (same as GNU `yes`), best-case size: 4.8GiB  
real 0m1.016s, user 0m0.180s, sys 0m0.834s
* SIZEPOW=14, buffer size: 16384, best-case size: 5.6GiB  
real 0m1.018s, user 0m0.090s, sys 0m0.926s
* SIZEPOW=15, buffer size: 32768, best-case size: 6.2GiB  
real 0m1.019s, user 0m0.057s, sys 0m0.959s
* SIZEPOW=16, buffer size: 64kiB, best-case size: 6.5GiB  
real 0m1.021s, user 0m0.023s, sys 0m0.993s
* SIZEPOW=17, buffer size: 128kiB (1/2 L2 cache size), best-case size: **6.6GiB**  
real 0m1.021s, user 0m0.017s, sys 0m1.002s
* SIZEPOW=18, buffer size: 256kiB (= L2 cache size), best-case size: **6.6GiB**  
real 0m1.020s, user 0m0.013s, sys 0m1.005s
* SIZEPOW=19, buffer size: 512kiB (2x L2 cache size), best-case size: 6.4GiB  
real 0m1.021s, user 0m0.000s, sys 0m1.019s (User time getting meaningless / too small for Linux to measure accurately.)
* SIZEPOW=20, buffer size: 1024kiB, best-case size: 6.2GiB
* SIZEPOW=21, buffer size: 2MiB, best-case size: 5.7GiB
* SIZEPOW=22, buffer size: 4MiB (1/2 L3 size), best-case size: 5.0GiB
* SIZEPOW=23, buffer size: 8MiB (L3 cache size), best-case size: 4.9GiB
* SIZEPOW=24, buffer size: 16MiB (2x L3 cache size), best-case size: 4.9GiB
* SIZEPOW=25, buffer size: 32MiB, best-case size: 4.8GiB
* ...
* SIZEPOW=28, buffer size: 256MiB, best-case size: 4.4GiB
**GNU coreutils 8.31 `yes`**: buffer size 8192, best case size: 4.7GiB
(vs. 4.8GiB for my 8k buffer version. Perhaps because of lower startup overhead. My statically linked executable makes literally no system calls before `write`, just a BSS pagefault or two, vs. GNU `yes` being dynamically has more overhead before it gets going. And not quite as tight a loop around `syscall`, probably involving indirect-call/ret into libc's write wrapper, so at least two different pages of code in user-space are touched between system calls. Two chances for iTLB or i-cache misses. (Making a system call tends to invalidate a lot, especially with Spectre / Meltdown / MDS mitigations enabled, but even without that if a lot of kernel code runs)
GNU `yes`'s buffer is 64-byte aligned (cache line) but not 4k-page aligned. IDK if that makes any difference or leads to more dTLB misses (from spanning 3 pages instead of 2). Being an odd multiple of 64 bytes (address ending in `0x440`) is not ideal for the L2 spatial prefetcher (which tries to complete 128B-aligned pairs of lines) but that's probably insignificant; 8kiB is small enough that we get lots of L1d hits and very few L2 misses overall, including both user and kernel space. (`perf stat -d`)
The fall-off at the high end of size is I think due to cache and TLB misses. You can run `perf stat -d` instead of `time` to see LLC-misses. (And LLC-loads is an indication of L2 load misses. Indeed, small buffers get mostly L2 hits, larger buffers get some misses.)
Note that the `time` real/user/system times are for the `timeout` process itself, not for just the `yes` workload. And that Linux's time accounting is somewhat granular, I think. `perf stat` gives more details, but I didn't want even the tiny overhead of the occasional HW performance-counter event interrupt.
---
## Further speedup ideas:
Spawning **multiple threads** (all writing with `O_APPEND`) might be a minor win, depending on how much they serialize each other when appending. (I'm hoping they just reserve space and then copy, so a 2nd call can reserve more space while an earlier one is still copying. Otherwise we might need **[`vmsplice`](http://man7.org/linux/man-pages/man2/vmsplice.2.html) + [`splice(2)`](http://man7.org/linux/man-pages/man2/splice.2.html) or something** to do the page-dirtying in user-space and **give pages to the kernel without further copying** (`SPLICE_F_GIFT` + `SPLICE_F_MOVE`)). But making a `clone` system call would probably take significantly more code.
Intel desktop CPUs can nearly saturate their memory bandwidth with a single core, unlike many-core Xeons with higher memory / uncore latency; [ironically/paradoxically worse *single-core* memory bandwidth](https://stackoverflow.com/questions/39260020/why-is-skylake-so-much-better-than-broadwell-e-for-single-threaded-memory-throug/47787231?noredirect=1#comment106169219_47787231) despite more memory controller channels for higher aggregate bandwidth than dual/quad-core client chips. With significant time spent in the kernel not bottlenecked on DRAM bandwidth, multiple threads could still help.
**Using [`writev(2)`](http://man7.org/linux/man-pages/man2/writev.2.html) to pass the same buffer multiple times with one system call** could give the best of both worlds: small buffer for L1 / L2 hits while copying to the pagecache, but lots of work done per syscall. Maybe a few % speedup; (**Tried it; got a 7.0G output with 20 io vecs for an 8kiB buffer**, up from 6.6G. Kernel CPU time is now 49.5% `clear_page_erms`, 13.2% `copy_user_enhanced_fast_string`. So yes, less time spent *copying*, more time spent just clearing. 37 bytes, up from 29, score 26.3.
Source on [Try it online!](https://tio.run/##dVRtb9s2EP7OX/EAQ7uks50odtzFbgYMQzcMWJsg/dCh2@BS0kliIpEqScVy/3x6pOTa2DrBgHzvd889J@kcNWm9m2rpmqenNTw5j63ylVjDdblBYzrtMfXwTVs4TA2c@kzXyW@TqivpWtZbuXOj8YxfZyFDztGccFor/YCpzrEjN2MFnj9ny@yMRfwUa@Xhv@k8W9CSLeC85HL5t52G5ztspW26FpIz204LUdYmlTU2HGy9GF4rsV7j57qGpdLhM1lDOTi3rwjetDAFZKymMlBPWedlWhNOqM@o9bh7d3sqxLvfP7y@vXkP@tQhmXPvYEAeAcr6CX5Mri6iKvVuVCXLocU1klevWLjG8vJyvkSPBdIdzxKGRL41NucmUKi6Fl8TSE4wFjyqlLOWc@/zBvQhbYnCWLid22yt8gSlh/xc@GwRZgtjysx3DEvaFQVXDZFCHPKqSbAcVXKsYbUQMs@HeS7OxTebUOYx0z7kmjXygTYsr4LUdq4CrOyPBE7IQm0Y8oO3iEbrWtEGvXVctc@qcoSRoRgr3f3yJ5SDJsp5fekOqfEV/ri5uY3bv3t9K/btB/g@7v7W/Pso4liuS0PudsJd9FETYgbNdFhMqPGe6b7Ccp5MFm@Q7bKa1zS/fDlbvmFYnXYz9go@zMAVeKHJZH7kdzVbRD9vu8wrE91PvGrYKC3BmYa2FfNOG@W4/S4y0NL3bGZq8npyFdZDOqPTuJ61q@yIw8Ue8PuOzzKwBYueLwtNl1VoqDF2F8QBnhBsieF03rh8PBYO3rKjI39iw8ojTDbrT4HFC34PtAmhcU0kMXLjr2D8Ack/MccxaxIxC@tcHVEnJGXbWHCzeXs38vKam8nD6XLzpI34V0T/n4hHDjnQiwmeSZ768KwPpH8Uz1SB8@B33wR2ha7EM6odBV38lIU6ezZhfXjwK59PyqBXjbQPSpdMV9saR24FmRrrYTSGEQqp4pHel7SvsR8jTnExT/ataeNRmroYdtFziQgYDTfwf8NQr/ymtKZrT85PuX/NjBDCUaQTZqnj9chalRqL86ulCFe74kXzivkjs/9gPD19AQ "Assembly (nasm, x64, Linux) ‚Äì Try It Online")).
As expected it doesn't come close to paying for itself in user-space code size to create the array of ptr,length pairs, although it was possible with a `loop` around 2 `push` instructions (4 bytes), but extra instructions outside the loop to get the args into place were necessary. Also, the call number `__NR_writev` is 20 so I used an array of 20 iovs, allowing the same trick as with `fd` = `__NR_write` to save a byte vs. `lea`.
There's still overhead per iovec (200x 2k buffer is slower than 20x 8k buffer). The sweet spot is around 4k or 8k buffers, with very minor gains for using a big vector (20x 8k seems enough). IOV\_MAX is "only" 1024, and isn't slower but is barely faster. ([Try it online! - flexible iov size version for perf experiments](https://tio.run/##dVRtb9s2EP7OX/EAQ4vEjV/kJsZqNwOKNRsCbEvgAF2wrnAp6SRzkUSNpGK5fz49UnIsIJu@SMd7ee6eeyhpLZVxsR9X0pZPTys4sg475bZiBdukGqVuKoexgyvrzGKsYdU3uox@Pds2OV3KYif3tndO@TX1FVLO5oLjQlUPGFcp9mQnfIDXr9kzmbKJnwJW6r9149iDmkwG6yTDpf8d1D0/YCdN2dSQXNk0lRB5oWNZYMPJxonutRSrFT4UBQzlFt/IaErBtd2W4HQNnUEGNJWAWkoaJ@OCcEJtQrXD@u72VIi767@ubm/@BP3bIJpz72BCHgFK2zP8GL3rjmJn@6No0bW4QvT@PRuXWFxcvF2gxRzxnmfxQ2KnTco9IFNFIYbpPdwAJ@FTdh2qeu4hTY5MG9i93eyMcgRVddUZdjr3k/khZeIaJiVusowxfaYQx/7VmfcI8UpliESbbHOQHIJ1gJV2YS@UuGKPXBcZs@jBPUIAf0QiLU1EV9j3O79YjM6PJa5vPm1@/3DPXESz@fkESGncF2IOqOXyqqSqkx0Kno5Ct/ZQM1DDTAhMSvlAG6Ufl36SurFbwMj2iMWupHIDZ6q8UWhe@DFbdF5ja/7yHmM5LHDQM97XXGH98z2URUWUcr/xHrHmJn@7ubkN6ltf3YpXVFgSHbGHfR1Mq7ypOKZKVXbk3zP9df939dWfGOIWrNN2dxxkV1JpyZ0YvygfbZL2FJiP@N3t2meG2UiiX@hn73yD6EsoMVx1JCaeg@VAWd2yVY@32fyx7sV0yb2k/raxPKnSL1LaFymPnHNkPjQUYj@buH0zn33BywwfyPpNJF/Qod6eNX0SYTq6@ng9mgahsrG@CwZfrMOt5LOP96PpaRDxzJf8p/R79qM@r6X7pfl@DlvF6vjgF9ZyTFWyLaV5UFXO0jC1tmSXkLE2DrrqdI5MqiJgsD57jMM@w7Tzt9Hw1nQS9xEtQ4QtUKfG/5ubWuU2udFNfTI7fZaM5aunuIlJbHnnslB5hfPZu4XwtCxZPDYdcCKenr4D "Assembly (nasm, x64, Linux) ‚Äì Try It Online") also needs only a couple changes to flip back to plain write instead of writev.
[Answer]
# [C (clang)](http://clang.llvm.org/), ~~88~~ 63 bytes, 2.5GB/s
```
b[2048];main(){for(wmemset(b,'\ny\ny',2048);write(1,b,8192););}
```
[Try it online!](https://tio.run/##S9ZNzknMS///PynayMDEItY6NzEzT0OzOi2/SKM8NzW3OLVEI0lHPSavEojUdUBqNK3LizJLUjUMdZJ0LAwtjTStNa1r//8HAA "C (clang) ‚Äì Try It Online") Edit: Saved 25 bytes thanks to @ceilingcat by assuming 4-byte wide characters.
[Answer]
## Bash, 16 bytes, 16TB output, score ~0 .0018554687
Thoroughly abuses the rules
```
trap '' TERM
yes
```
It ignores `timeout`'s SIGTERM (running an empty command) and so continues beyond the 1 second that the benchmark script intended to set. **This will fill your disk unless you kill it with a different signal or set a quota or other size limit.**
[Answer]
# [Perl 5 (cperl)](http://perl11.org/cperl/), 26 bytes
```
while(1){print"y\n"x 9**4}
```
[Try it online!](https://tio.run/##K0gtyjHVTS4AUv//l2dk5qRqGGpWFxRl5pUoVcbkKVUoWGppmdT@/w8A "Perl 5 (cperl) ‚Äì Try It Online")
# [R](https://www.r-project.org/), 18 bytes
```
repeat{cat('y\n')}
```
[Try it online!](https://tio.run/##K/r/vyi1IDWxpDo5sURDvTImT12z9v9/AA "R ‚Äì Try It Online")
Improved thanks to @[JDL](https://codegolf.stackexchange.com/users/55516/jdl)
# [Squirrel](http://www.squirrel-lang.org/), 24 bytes
```
while(1){::print("y\n")}
```
[Try it online!](https://tio.run/##Ky4szSwqSs35/788IzMnVcNQs9rKqqAoM69EQ6kyJk9Js/b/fwA "Squirrel ‚Äì Try It Online")
# [JavaScript (Node.js)](https://nodejs.org), 26 bytes
```
while(1){console.log('y')}
```
[Try it online!](https://tio.run/##y0osSyxOLsosKNHNy09J/f@/PCMzJ1XDULM6OT@vOD8nVS8nP11DvVJds/b/fwA "JavaScript (Node.js) ‚Äì Try It Online")
# [Python 3](https://docs.python.org/3/), 28 bytes
```
while1:print(end='y\n'*9**4)
```
[Try it online!](https://tio.run/##K6gsycjPM/7/vzwjMyfV0KqgKDOvRCM1L8VWvTImT13LUkvLRPP/fwA "Python 3 ‚Äì Try It Online")
# [Julia 1.0](http://julialang.org/), 27 bytes
```
while(1==1) println('y')end
```
[Try it online!](https://tio.run/##yyrNyUw0rPj/vzwjMydVw9DW1lBToaAoM68kJ09DvVJdMzUv5f9/AA "Julia 1.0 ‚Äì Try It Online")
## [WHILE Programming Language](https://www.oxfordreference.com/view/10.1093/oi/authority.20110803122041931)
Performant but not participating because of many bytes...
You can't try it online! Sorry:)
But here are [Docs](https://www.scss.tcd.ie/Matthew.Hennessy/splexternal2015/notes/WhileSlides2to1.pdf),[doc](http://profs.sci.univr.it/~merro/files/WhileExtra_l.pdf) and a java-based [IDE](http://www2.mta.ac.il/~tal/WIDE/wide.zip)
[Answer]
# [C (gcc)](https://gcc.gnu.org/), 67 bytes
```
b[1<<16];main(){for(wmemset(b,'\ny\ny',1<<16);~write(1,b,1<<18););}
```
Your times may vary. I'm running this inside a VM on a weak computer.
* `b[1<<16];` is an integer array of \$2^{18}\$ bytes.
* `wmemset(b,'\ny\ny',1<<16);` sets that array to a pattern of `y\ny\n`. The characters are reversed due to the endianness of the x86 platform.
* `~write(1,b,1<<18)` writes that array over and over until the write fails. (The `~` makes a `-1` error return -> false; without it we iterate until the process is killed, saving 1 byte.)
May be faster on other systems if I increase the buffer size to 1 megabyte but there's no noticeable difference on mine. This really should be an average.
[Try it online!](https://tio.run/##HYpLCoAgFACPk4IuJIhA79ABqoWKhuAntJCIOnqvCGY2w2i6aA2gRiYE62YepIsInzZlVIMJxWxIkWaKx0dD/gnzu2a3GcSI@kuPOeYXwKOtl0sBOrRA7R5z8p7KT5/SWl4 "C (gcc) ‚Äì Try It Online")
[Answer]
### x86 machine code - 21 15 bytes, score : 175119.036
Using [write()](https://man7.org/linux/man-pages/man2/write.2.html) syscall to print `y\n`
This is a NASM listing (`y.asm`) :
```
6  00000000 6668790A                    push word 0x0a79
7  00000004 43                          inc ebx
8  00000005 89E1                        mov ecx, esp
9  00000007 B202                        mov dl, 2
10                                  .loop:
11 00000009 B004                        mov al, 4
12 0000000B CD80                        int 0x80
13 0000000D EBFA                        jmp .loop
```
Using `score.sh` to get a score (`./score.sh y "./y"`), score are : 175119.036
[Answer]
# [brainfuck](https://github.com/TryItOnline/brainfuck), 30\*971956224/621731~46899.2
```
>+[>+[<]>->+]++++++++++<[.>.<]
```
[Try it online!](https://tio.run/##SypKzMxLK03O/v/fTjsaiGxi7XTttGO14cAmWs9Ozyb2/38A "brainfuck ‚Äì Try It Online")
The BF JIT that I'm using prints each character in a separate syscall. An implementation that coalesces multiple `.` commands into one syscall would likely perform better.
Thanks to the [list of BF constants](https://esolangs.org/wiki/Brainfuck_constants).
[Answer]
# [Rust](https://www.rust-lang.org/), ~~49~~ 48 bytes \$\times\,\frac{32186368}{744521728}\approx2.075\$
Plain Rust, compiled with `-C target-cpu=native -C opt-level=3`. Clearly not the winner, only for reference; not bad, btw :)
```
fn main(){loop{print!("{}","y\n".repeat(8192))}}
```
-1 byte thanks to [Anders Kaseorg](https://codegolf.stackexchange.com/users/39242/anders-kaseorg)
[Try it online!](https://tio.run/##KyotLvn/Py1PITcxM09DszonP7@guqAoM69EUUOpulZJR6kyJk9Jryi1IDWxRMPC0NJIU9O6tvb/fwA "Rust ‚Äì Try It Online")
[Answer]
# [Python 3](https://docs.python.org/3/), 34 bytes, 1.9GB/s, score \$\le\$ 31.507
```
a='y\n'*2**17
while 1:print(end=a)
```
[Try it online!](https://tio.run/##K6gsycjPM/7/P9FWvTImT13L2MjczIKrPCMzJ1XB0KqgKDOvRCM1L8U2UfP/fwA "Python 3 ‚Äì Try It Online")
[Answer]
# [Jyxal `0ea7043bf37cd78106cde8f664e452f87286673b`](https://github.com/Vyxal/Jyxal/tree/0ea7043bf37cd78106cde8f664e452f87286673b), ~31.551 on my machine
```
{9999`y\n`*‚Ç¥}
```
Timed using an aging laptop with an Intel Core i5 4th gen, 8 GB ram, using WSL. It uses Vyxal's codepage, so I modified `score.sh` to use the `-m` flag instead of `-c`. Jyxal is a flavor of Vyxal designed for maximum speed. Unfortunately, I could not apply my push-pop optimizations in this case that *really* make Jyxal fast. Also for some weird reason multiplying the string inside the loop seems to be faster than outside...
```
{9999`y\n`*‚Ç¥} # Ze program
{           } # An infinite loop
     `y\n`    # The string "y\n"
 9999     *   # Repeated 9999 times...
           ‚Ç¥  # Printed without a newline
```
## How to run
Jyxal isn't exactly released yet, you'd have to built it yourself. Clone the repo at commit `0ea7043bf37cd78106cde8f664e452f87286673b` and then run `./gradlew shadowJar`. You will find the compiled compiler in `/build/libs/`. Then create a file with the Jyxal program, and compile it with `java -jar Jyxal-1.0-SNAPSHOT-all.jar yourProgram.txt`. The run the compiled program using `java -jar yourProgram.jar`. All Java-related steps require Java 17 or higher.
[Answer]
# [Japt](https://github.com/ETHproductions/japt), 6 bytes
No clue how the scoring in this challenge works.
```
@Opy}a
```
[Try it online!](https://tio.run/##y0osKPn/38G/oLI28f9/AA)
```
@          :Function
 Opy       :  Print "y"
    }      :End function
     a     :Call repeatedly until it returns a truthy value
           :(Japt's O.p() method returns undefined)
```
[Answer]
# x86-32 Linux, 26 bytes (ungolfed), 1.5M
[`write` syscall test](https://stackoverflow.com/a/50940154/3163618). Produces a very underwhelming result. 
```
main:
    push    $0x0A79     # "y\n"
    mov     $1, %ebx    # write to stdout (fd=1)
    mov     %esp, %ecx  # use chars on stack
    mov     $2, %edx    # write 2 chars
loop:
    mov     $4, %eax    # sys_write call number 
    int     $0x80
    jmp     loop
```
[Answer]
# [Python 3](https://docs.python.org/3/), 18 bytes \$\times\frac{16834568}{622668}\approx486.65\$
```
while 1:print('y')
```
[Try it online!](https://tio.run/##K6gsycjPM/7/vzwjMydVwdCqoCgzr0RDvVJd8/9/AA "Python 3 ‚Äì Try It Online")
[Answer]
# [05AB1E (legacy)](https://github.com/Adriandmen/05AB1E/tree/fb4a2ce2bce6660e1a680a74dd61b72c945e6c3b) / [05AB1E](https://github.com/Adriandmen/05AB1E), 4 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage), score: *waiting for OP*
```
['y,
```
Or alternatively:
```
'y[=
```
[Try it online.](https://tio.run/##MzBNTDJM/f9fvTLa9v9/AA)
Not sure which combination is the shortest, so for now this answer has four possible variations:
* [05AB1E (legacy)](https://github.com/Adriandmen/05AB1E/tree/fb4a2ce2bce6660e1a680a74dd61b72c945e6c3b) with program `['y,`
* [05AB1E (legacy)](https://github.com/Adriandmen/05AB1E/tree/fb4a2ce2bce6660e1a680a74dd61b72c945e6c3b) with program `'y[=`
* [05AB1E](https://github.com/Adriandmen/05AB1E) with program `['y,`
* [05AB1E](https://github.com/Adriandmen/05AB1E) with program `'y[=`
The 05AB1E (legacy) version is compiled and run in Python 3, and the 05AB1E version is compiled and run in Elixir. Based on performance on TIO for most challenges I did, I assume the legacy version will score much better.
I will leave just one of these four combinations with the largest output after OP's local test. The links provided contain instructions on how to install and run both 05AB1E and 05AB1E (legacy) locally.
**Explanation:**
```
[     # Loop indefinitely:
 'y  '#  Push string "y"
   ,  #  Pop and output it with trailing newline
'y   '# Push string "y"
  [   # Loop indefinitely:
   =  #  Output with trailing newline (without popping)
```
[Answer]
# [Pyth](https://github.com/isaacg1/pyth), 10 bytes \$\times\frac{1894125568}{1599025152}\approx11.846\$
```
#p*^9 5"y
```
**Explanation:**
```
#           :  Loop till error
   ^9 5     :  Evaluates to 9 ^ 5 (59049)
  *    "y\n :  Concatenates "y\n" to itself 59049 times
 p          :  Print without trailing newline
```
[Try it online!](https://tio.run/##K6gsyfj/X7lAK85SwVSpkuv/fwA "Pyth ‚Äì Try It Online")
[Answer]
# GFortran, 24 bytes, score: 49.179
`yes1.f90` ¬† [Try it online](https://tio.run/##S8svKilKzNNNT4Mw/v9PybcuKMrMK9HSUa9Ut07NS0nJ5wKS//8DAA)
```
do;print*,'y';enddo
end
```
Might be faster to use [`FPUT`](https://gcc.gnu.org/onlinedocs/gfortran/FPUT.html#FPUT)??, for **52 bytes**:   
`yes2.f90` ¬† [Try it online](https://tio.run/##S8svKilKzNNNT4Mw/v9PybdOTszJUUgrKC3RUK9U10Ti5qWWx@dk5qVqqKtralqn5qWk5HMByf//AQ)
```
do;call fput('y');call fput(new_line(''));enddo
end
```
Run the code
```
//Compile
$ gfortran -std=gnu -Wextra -Wall -pedantic -ffree-form -fcheck=all -fbacktrace yes1.f90 -o yes1.a
$ gfortran -std=gnu -Wextra -Wall -pedantic -ffree-form -fcheck=all -fbacktrace yes2.f90 -o yes2.a
//Run the test
$ timeout 1s yes > out0
$ timeout 1s yes1.a > out1
$ timeout 1s yes2.a > out2
//File sizes
-rw-r--r--  1  staff  29306880  6 Mar 18:43 yes.out
-rw-r--r--  1  staff        24  6 Mar 18:57 yes1.f90
-rw-r--r--  1  staff  14302020  6 Mar 18:51 yes1.out
-rw-r--r--  1  staff        52  6 Mar 18:57 yes2.f90
-rw-r--r--  1  staff  18071552  6 Mar 18:39 yes2.out
//Scores
$ bc<<<"scale=3;24*29306880/14302020"
49.179
$ bc<<<"scale=3;52*29306880/18071552"
84.329
```
My system (inferior to the OP):
```
$ neofetch --off
OS: macOS 11.2 20D64 x86_64 
Host: MacBookPro13,2 
Kernel: 20.3.0 
CPU: Intel i5-6267U (4) @ 2.90GHz 
GPU: Intel Iris Graphics 550 
Memory: 5500MiB / 8192MiB 
```
[Answer]
# [C (clang)](http://clang.llvm.org/), ~~57~~ 54 bytes \$\times\frac{44152832}{45940736}\approx51.8984\$
Saved 3 bytes thanks to @S.S.Anne!!!
```
#define p putchar_unlocked
main(){for(;;p(10))p('y');}
```
[Try it online!](https://tio.run/##S9ZNzknMS///XzklNS0zL1WhQKGgtCQ5I7EovjQvJz85OzWFKzcxM09Dszotv0jD2rpAw9BAU7NAQ71SXdO69v9/AA "C (clang) ‚Äì Try It Online")
This is on my ancient tablet, probability better on my laptop that's far away right now - on holiday! :))))
]