📜 ⬆️ ⬇️

Crystal High Performance Services, Newbie Introduction

Introduction


DISCLAIMER

author's opinion may not coincide with your opinion, welcome to the comments.


In prehistoric times, high-performance Web applications could be written mainly in C or C ++. Maintaining such applications was not just expensive, but very expensive.


The need for a programming environment in which it is convenient to write, read and modify high-performance applications, appeared long ago.


First of all, the terms "performance" and "reliability" refer to Erlang. It is great in its niche, but the syntax makes you want something better. Actually, this is why Elixir appeared, but this is not about this ecosystem.


If, on the other hand, we lower the reliability bar a little, then we have a wide choice, including Node , Go , Nim and Crystal . You can look at typical performance benchmarks , including more extensive ones .


All of these programming environments offer garbage collection, which reduces the complexity of code maintenance.


With this, Node offers everyone an understandable programming language (and variations on the topic), but dynamic typing reduces productivity by several times relative to other applicants.


If we need more requests per second, the choice for today is Go . This programming environment has excellent performance characteristics, support from large companies and a considerable number of active projects.


So why Crystal?


Llvm


Crystal provides a frontend for LLVM infrastructure, allowing you to compile code for all supported platforms (x64, ARM, Web Assembly etc.).


Static typing without specifying types


Crystal can in most cases deduce the types of data used.


For example, we send somewhere to the speak method in one case a string, in the other case an integer.


In such a case, Crystal at compile time knows that the method speak takes a parameter of the derived type String | Int32 .


We can write this code:


speak(15) speak("Whatever") def speak( thing ) thing.say_every #  ,   thing  (Int32  String),      say_every #      Object,    ,   String  Int32 if thing.is_a?(String) #  Crystal  ,    thing  String,     . return thing.sub(/\Athe\s+/, "") elsif thing.responds_to?(:to_s) #  Crystal  ,   thing   to_s,     return thing.to_s end end 

It is important to note that all values ​​are objects, including numbers and strings. The price of objectivity is zero, because operations on objects are defined at the stage of static analysis in the compiler.


Check for empty value


In general, a special check in the code for an empty value is not required. For example, in this example, an attempt to pass a null value will result in a compilation error, because my_string is of type (String or Nil), and Nil has no upcase method:


 if rand(2) > 0 my_string = "hello world" end puts my_string.upcase 

Concurrency model


Crystal supports green streams, channels, and the SO_REUSEPORT option - similar to Go. Currently, we are working on high-quality support for multithreading at the operating system level, which will lead to efficient applications on several processor cores.


Libraries


Crystal actually has its own dependency manager - Shards .


The functionality is similar to ruby ​​bundler, perl carton etc. At the same time dependences are described in the shards.yml project.


BDD, a common interface for working with RDBMS and other amenities are included in the standard library .


I will not mention the various libraries for data analysis and so on, for this there is an Awesome Crystal list.


From what is not included in the standard distribution, but useful for web applications:


Kemal


 require "kemal" # Matches GET "http://host:port/" get "/" do "Hello World!" end # Creates a WebSocket handler. # Matches "ws://host:port/socket" ws "/socket" do |socket| socket.send "Hello from Kemal!" end Kemal.run 

crystal-pg


 PG_DB.query_one("select ARRAY[1, null, 3]", &.read(Array(Int32?)) # => [1, nil, 3] PG_DB.query_one("select '{hello, world}'::text[]", &.read(Array(String)) # => ["hello", "world"] 

Remarkdown


 require "remarkdown" Remarkdown.to_html("Hello **world**") 

Remarks



')

Source: https://habr.com/ru/post/328364/


All Articles