Crystal - Ruby와 비슷하며 빠른 프로그래밍 언어

올 초쯤에 Crystal이란 언어에 대해 잠깐 이야기들은적이 있습니다. Ruby 문법과 유사하다는 것만 듣고 드디어 조금 더 살펴봤네요. 아직 정식 릴리즈도 아닌 상태이니 어떤 언어인지 정도만 정리해둘까 합니다.

Crystal?

Crystal은 루비 문법 스타일과 유사한 형태를 가지며 Static typing & LLVM 컴파일러를 사용하는 프로그래밍 언어입니다. Ruby의 자유로운 문법 스타일과 C의 퍼포먼스(런타임 성능)을 모두 챙기려고 하는 언어지요.

사실 아직 직접적으로 써보진 않아서 리뷰하기엔 어렵습니다. 그냥 소개 정도만 할까합니다. 우선 문법 스타일은 루비랑 거의 유사합니다. 예제로 나와있는 웹 서버 코드만 봐도 거의 동일하단 것을 알 수 있습니다.

# A very basic HTTP server
require "http/server"

server = HTTP::Server.new do |context|
  context.response.content_type = "text/plain"
  context.response.print "Hello world, got #{context.request.path}!"
end

puts "Listening on http://127.0.0.1:8080"
server.listen(8080)

그냥 루비라고 봐도 무방할 정도이지요. 다만 go처럼 바로 run 하거나 build 후 런을 할 수 있도록 선택할 수 있습니다. 인터프리터 언어인 루비보단 당연히 성능이 좋을 수 밖에 없습니다. 이외에도 Null reference check, C Binding 등 여러 기능을 장점으로 내세우고 있습니다. 다만 아직 프로젝트가 많이 발달하지 않았다는 점이 단점으로 보입니다.

git topic을 비교해봤을 때 python 같은 언어보다 상대적으로 적은 ruby보다도 한참 못미치는 숫자의 repo가 존재합니다.

  • Ruby : 14,495 (https://github.com/topics/ruby)
  • Crystal : 830 (https://github.com/topics/crystal)

이러다 보니 자연스럽게 라이브러리 지원쪽에선 밀릴 수 밖에 없습니다. 그리고 unix system만 지원하는 것으로 알고있습니다. 범용성 측면에선 Ruby가 좋을 수 밖에 없을 것 같네요. C-Binding은 Crystal 내부에서 C단 코드 호출이 바로 가능합니다.

# Fragment of the BigInt implementation that uses GMP
@[Link("gmp")]
lib LibGMP
  alias Int = LibC::Int
  alias ULong = LibC::ULong

  struct MPZ
    _mp_alloc : Int32
    _mp_size : Int32
    _mp_d : ULong*
  end

  fun init_set_str = __gmpz_init_set_str(rop : MPZ*, str : UInt8*, base : Int) : Int
  fun cmp = __gmpz_cmp(op1 : MPZ*, op2 : MPZ*) : Int
end

struct BigInt < Int
  def initialize(str : String, base = 10)
    err = LibGMP.init_set_str(out @mpz, str, base)
    raise ArgumentError.new("invalid BigInt: #{str}") if err == -1
  end

  def <=>(other : BigInt)
    LibGMP.cmp(mpz, other)
  end
end

Install & Use

hombrew, source.list 등록 후 apt 같은 패키지 매니저로 설치가 가능합니다. source.lit 등록은 공식 홈에서 setup.sh로 제공하고 있습니다.

# Install script
curl -sSL https://dist.crystal-lang.org/apt/setup.sh | sudo bash

# Linux
apt-get install crystal

# macos의 경우에는 brew로 한줄로 설치 가능합니다. 
brew install crystal

기본 확장자는 .cr 이며 crystal 명령 자체에 run, build 등 옵션을 지원합니다.

vim test.cr
puts Hi
puts "I am Crystal!"
# Run
crystal run test.cr

# Build and run
crystal build test.cr
./test

Conclusion

많이 써보고 소개하는 글은 아니라 영양가는 없습니다. 다만, 이런 언어도 쓰이고 있따 정도만 공유드리고 싶었을 뿐입니다. 성능 고려했을 땐 Ruby의 서브 언어 느낌으로 Crystal을 써보는 것도 좋긴하겠지만, Ruby 3버전대 부턴 Static typing을 지원한다는 이야기도 있어 아직 지켜봐야할 것 같습니다.

그나저나 benchmark 자료들 보면 ruby랑 정말 차이가 많이 나네요.

# https://github.com/kostya/benchmarks

Language   times   memory
Crystal      3.37       1.3
Ruby          147.32   7.4