47. 문자열 보간의 컴파일러 변환과 로깅에서의 숨은 비용

난이도 상 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C#
// 문제 47 — 문자열 보간($"...")의 컴파일러 변환과 로깅에서의 비용
//
// 주제: 보간 문자열 $"..." 은 컴파일러가 무엇으로 낮추는가(lowering)? 대상이 string 일 때와
//   보간 문자열 핸들러(interpolated string handler)를 받는 API 일 때 무엇이 달라지는가?
//   값 형식을 보간에 넣으면 박싱이 일어나는가? 로그 레벨이 꺼져 있어도 문자열이 만들어지는가?
//
// 과제:
//   1) (A) 처럼 string 에 대입하는 보간이 C# 10+ 에서 어떤 형태로 낮춰지는지,
//      과거 string.Format 경로와 비교해 박싱/중간 배열 관점에서 설명하라.
//   2) (B) StringBuilder.Append(보간) 은 왜 중간 string 을 만들지 않는지, (C) 의 string.Format 과
//      비용을 비교하라.
//   3) (D) 처럼 string 매개변수를 받는 로깅에 보간을 넘기면, 레벨이 꺼져 있어도 Expensive() 와
//      문자열 조립이 실행되는지 예측하고, 이를 피하는 방법을 설명하라.

using System;
using System.Text;

public static class InterpolationDemo
{
    static int Expensive() { Console.WriteLine("Expensive() 호출됨"); return 999; }

    public static void Run(int x, int y, int hp, bool debugEnabled)
    {
        string s = $"pos=({x},{y})";                    // (A)

        var sb = new StringBuilder();
        sb.Append($"hp={hp} ");                         // (B)

        string f = string.Format("hp={0}", hp);         // (C)

        // 아래 LogDebug 는 string 매개변수를 받는다(핸들러 아님).
        LogDebug(debugEnabled, $"expensive={Expensive()}");  // (D)

        Console.WriteLine(s + " / " + sb + " / " + f);
    }

    static void LogDebug(bool enabled, string message)
    {
        if (enabled) Console.WriteLine("[DBG] " + message);
    }
}
내 리뷰 · C#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.