본문으로 건너뛰기
블록체인Mar 28, 2026

Deep EVM #7: Yul의 가스 효율적 루프와 조건문

OS
Open Soft Team

Engineering Team

루프는 가스가 죽는 곳이다

대부분의 스마트 컨트랙트에서 가장 큰 가스 소비자는 반복입니다. 100개 요소 배열을 순회하는 함수는 본문을 100번 실행합니다 — 본문 안의 모든 옵코드가 100배로 곱해집니다.

Yul For 루프의 해부학

for { let i := 0 } lt(i, 10) { i := add(i, 1) } {
    // 본문
}

반복당 루프 오버헤드:

  • 조건 검사: 23 가스
  • 후행 반복: 6 가스
  • 점프 복귀: 11 가스
  • 반복당 총 오버헤드: 40 가스

벤치마크 결과 (100개 요소)

방법반복당 가스총합 (100요소)Solidity 대비 절감
Solidity (checked)~737,300기준
Solidity (unchecked)~535,30027%
Yul~434,30041%

루프 언롤링

루프 언롤링은 반복당 여러 요소를 처리하여 요소당 오버헤드를 줄입니다:

function sumUnrolled(offset, length) -> total {
    let end := add(offset, mul(length, 0x20))
    let endAligned := sub(end, mod(mul(length, 0x20), 0x80))
    for { } lt(offset, endAligned) { offset := add(offset, 0x80) } {
        total := add(total, calldataload(offset))
        total := add(total, calldataload(add(offset, 0x20)))
        total := add(total, calldataload(add(offset, 0x40)))
        total := add(total, calldataload(add(offset, 0x60)))
    }
    for { } lt(offset, end) { offset := add(offset, 0x20) } {
        total := add(total, calldataload(offset))
    }
}

Yul에서 안전한 unchecked 산술

Yul의 모든 산술은 기본적으로 unchecked입니다. 오버플로우 검사가 필요할 때:

function safeAdd(a, b) -> c {
    c := add(a, b)
    if lt(c, a) { revert(0, 0) }
}

결론

Yul의 루프 최적화는 영리한 트릭이 아닙니다 — 루프 본문의 모든 옵코드의 정확한 가스 비용을 이해하고 체계적으로 낭비를 제거하는 것입니다. 스토리지 읽기 캐시, 타이트 루프 언롤, 조기 종료, 반복 대신 비트 연산 선호.