Incremental compilation exploration

Oh no, on the contrary, it is good. Perso, I wish I had seen this comment 3 years ago :grin:
I would have kept Crystal for some small microservices. Because the main project takes a 40 / 50 seconds to rebuild in dev. Unusable to code like that, we have refacto all the project for months in Elixir.

2 Likes

I’ve been thinking about profiling compilation of some of my apps to see if there are any obvious hotspots that could be optimized.

Also @asterite’s explanation of the type-checking process has me wondering if there are additional ways to cache previous type-checking results. I always compile my apps with --stats --progress, showing which modules were not cached in the current compilation from the previous one.

For one of my services (a scheduling app), a cached compilation looks like this:

Macro runs:
 - /Users/jamie/Code/calendars/lib/armature/src/template/compile.cr: reused previous compilation (00:00:00.003791208)
 - /opt/homebrew/Cellar/crystal/1.9.2/share/crystal/src/ecr/process.cr: reused previous compilation (00:00:00.003195625)

Codegen (bc+obj):
 - all previous .o files were reused

real	0m4.102s
user	0m3.932s
sys 	0m0.795s

Inside one of the routing blocks, I added the following code:

if false
  puts "hello world"
end
In the output, there were 352 modules that could not be reused, resulting in a compilation time of almost 75% longer.

These modules were not reused:

  • _main (_main.bc)
  • Array(String) (A-rray40S-tring41.bc)
  • Int32 (I-nt32.bc)
  • Float64 (F-loat64.bc)
  • Crystal::System::Dir (C-rystal5858S-ystem5858D-ir.bc)
  • String (S-tring.bc)
  • Slice(T) (S-lice40T-41.bc)
  • Slice(UInt8) (S-lice40U-I-nt841.bc)
  • Char (C-har.bc)
  • Path (P-ath.bc)
  • Crystal::Hasher (C-rystal5858H-asher.bc)
  • File (F-ile.bc)
  • Process (P-rocess.bc)
  • Tuple(*T) (T-uple4042T-41.bc)
  • Tuple(Int64, Int64) (T-uple40I-nt644432I-nt6441.bc)
  • UInt16 (U-I-nt16.bc)
  • StaticArray(UInt8, 2) (S-taticA-rray40U-I-nt84432241.bc)
  • IO::Decoder (I-O-5858D-ecoder.bc)
  • Crystal::System::Signal (C-rystal5858S-ystem5858S-ignal.bc)
  • Hash(UInt64, UInt64) (H-ash40U-I-nt644432U-I-nt6441.bc)
  • Time (T-ime.bc)
  • Time::Location (T-ime5858L-ocation.bc)
  • Armature::Route::Response (A-rmature5858R-oute5858R-esponse.bc)
  • HTTP::Server::Response (H-T-T-P-5858S-erver5858R-esponse.bc)
  • HTTP::WebSocket::Protocol (H-T-T-P-5858W-ebS-ocket5858P-rotocol.bc)
  • HTTP::Cookie (H-T-T-P-5858C-ookie.bc)
  • HTTP (H-T-T-P-.bc)
  • IO+ (I-O-43.bc)
  • Compress::Gzip::Writer (C-ompress5858G-zip5858W-riter.bc)
  • Compress::Gzip::Reader (C-ompress5858G-zip5858R-eader.bc)
  • IO::Memory (I-O-5858M-emory.bc)
  • IO::Delimited (I-O-5858D-elimited.bc)
  • HTTP::Status (H-T-T-P-5858S-tatus.bc)
  • Log::Metadata (L-og5858M-etadata.bc)
  • Log::AsyncDispatcher (L-og5858A-syncD-ispatcher.bc)
  • JSON::Builder (J-S-O-N-5858B-uilder.bc)
  • Float::Printer (F-loat5858P-rinter.bc)
  • Time::DayOfWeek (T-ime5858D-ayO-fW-eek.bc)
  • Hash(String, String) (H-ash40S-tring4432S-tring41.bc)
  • Hash(String, Set(String)) (H-ash40S-tring4432S-et40S-tring4141.bc)
  • Regex (R-egex.bc)
  • Hash(Int32, PG::Decoders::Decoder) (H-ash40I-nt324432P-G-5858D-ecoders5858D-ecoder41.bc)
  • DB (D-B-.bc)
  • URI (U-R-I-.bc)
  • Log::Emitter (L-og5858E-mitter.bc)
  • URI::Params (U-R-I-5858P-arams.bc)
  • DB::Pool::Options (D-B-5858P-ool5858O-ptions.bc)
  • TCPSocket (T-C-P-S-ocket.bc)
  • OpenSSL::SSL::Socket::Client (O-penS-S-L-5858S-S-L-5858S-ocket5858C-lient.bc)
  • Base64 (B-ase64.bc)
  • DB::Database (D-B-5858D-atabase.bc)
  • UUID (U-U-I-D-.bc)
  • JSON::PullParser (J-S-O-N-5858P-ullP-arser.bc)
  • JSON::Lexer::IOBased (J-S-O-N-5858L-exer5858I-O-B-ased.bc)
  • Range(Time::Span, Time::Span) (R-ange40T-ime5858S-pan4432T-ime5858S-pan41.bc)
  • NATS::Client (N-A-T-S-5858C-lient.bc)
  • Tuple(Time::Span, Time::Span) (T-uple40T-ime5858S-pan4432T-ime5858S-pan41.bc)
  • NATS::Subscription (N-A-T-S-5858S-ubscription.bc)
  • NATS::KV::Client (N-A-T-S-5858K-V-5858C-lient.bc)
  • NATS::JetStream::Errors (N-A-T-S-5858J-etS-tream5858E-rrors.bc)
  • Time::Format::Parser (T-ime5858F-ormat5858P-arser.bc)
  • Bugsnag::Middleware (B-ugsnag5858M-iddleware.bc)
  • Bugsnag (B-ugsnag.bc)
  • HTTP::Request (H-T-T-P-5858R-equest.bc)
  • Google::Client (G-oogle5858C-lient.bc)
  • Google::HTTPClient (G-oogle5858H-T-T-P-C-lient.bc)
  • DB::Pool(T) (D-B-5858P-ool40T-41.bc)
  • Array(HTTP::Client) (A-rray40H-T-T-P-5858C-lient41.bc)
  • Hash(HTTP::Client, Nil) (H-ash40H-T-T-P-5858C-lient4432N-il41.bc)
  • DB::Pool(HTTP::Client) (D-B-5858P-ool40H-T-T-P-5858C-lient41.bc)
  • HTTP::Client+ (H-T-T-P-5858C-lient43.bc)
  • Microsoft::Client (M-icrosoft5858C-lient.bc)
  • Microsoft::HTTPClient (M-icrosoft5858H-T-T-P-C-lient.bc)
  • Stripe (S-tripe.bc)
  • Stripe::PaymentIntent::SetupFutureUsage (S-tripe5858P-aymentI-ntent5858S-etupF-utureU-sage.bc)
  • Stripe::PaymentIntent::Status (S-tripe5858P-aymentI-ntent5858S-tatus.bc)
  • StripeEventWorker (S-tripeE-ventW-orker.bc)
  • BackgroundJob (B-ackgroundJ-ob.bc)
  • Stripe::Client (S-tripe5858C-lient.bc)
  • HTTP::Client (H-T-T-P-5858C-lient.bc)
  • Array(Proc(HTTP::Request, Nil)) (A-rray40P-roc40H-T-T-P-5858R-equest4432N-il4141.bc)
  • Armature::Session::NATSStore (A-rmature5858S-ession5858N-A-T-S-S-tore.bc)
  • Web (W-eb.bc)
  • HTTP::Server (H-T-T-P-5858S-erver.bc)
  • HTTP::ErrorHandler (H-T-T-P-5858E-rrorH-andler.bc)
  • HTTP::StaticFileHandler (H-T-T-P-5858S-taticF-ileH-andler.bc)
  • HTTP::WebSocketHandler (H-T-T-P-5858W-ebS-ocketH-andler.bc)
  • Socket::IPAddress (S-ocket5858I-P-A-ddress.bc)
  • MIME::MediaType (M-I-M-E-5858M-ediaT-ype.bc)
  • Armature::Session::NATSStore::Session (A-rmature5858S-es-c50c018892e6b40e59837896086a55bd.bc)
  • Armature::Route::Request (A-rmature5858R-oute5858R-equest.bc)
  • UserQuery (U-serQ-uery.bc)
  • Array(Interro::JoinClause) (A-rray40I-nterro5858J-oinC-lause41.bc)
  • API::Settings::Availability (A-P-I-5858S-ettings5858A-vailability.bc)
  • UserAvailabilityQuery (U-serA-vailabilityQ-uery.bc)
  • Array(API::Settings::AvailabilityRequest) (A-rray40A-P-I-585-f4d56d2cb5ddf0a639b3a09a1617c718.bc)
  • Hash(UserAvailability.class, String) (H-ash40U-serA-vailability46class4432S-tring41.bc)
  • UserAvailability (U-serA-vailability.bc)
  • API::Settings::AvailabilityRequest (A-P-I-5858S-ettings5858A-vailabilityR-equest.bc)
  • API::Settings::AvailabilityRequest::DayWithTimeString (A-P-I-5858S-ettin-76904389fdfbf9546d0859e94dd198c3.bc)
  • Slice(Tuple(API::Settings::AvailabilityRequest, Int32)) (S-lice40T-uple40A-8b73c353ccab8e285461c8517e40643a.bc)
  • SettingQuery (S-ettingQ-uery.bc)
  • Interro::DynamicQuery(String, SettingQuery) (I-nterro5858D-yna-087b661c081d7847383897a7d2bafe51.bc)
  • TimeSpanConverter (T-imeS-panC-onverter.bc)
  • Interro::DynamicQuery(Tuple(UUID, Range(Time::Span, Time::Span)), UserAvailabilityQuery) (I-nterro5858D-yna-d1811334912e9f4fa7b80a9dbb502924.bc)
  • Array(Tuple(UUID, Range(Time::Span, Time::Span))) (A-rray40T-uple40U-048701c3198ba190cffafdd497b7bcf6.bc)
  • Array(Int32 | String | UUID) (A-rray40I-nt323212432S-tring3212432U-U-I-D-41.bc)
  • BackgroundJob::Worker::AsyncProxy(StripeEventWorker::PerformArgs) (B-ackgroundJ-ob58-6b453a8aed6e75de93d4c8cb4e756eef.bc)
  • Range(Int32, Int64) (R-ange40I-nt324432I-nt6441.bc)
  • NATS::JetStream::PubAck (N-A-T-S-5858J-etS-tream5858P-ubA-ck.bc)
  • (NATS::JetStream::ErrorResponse | NATS::JetStream::PubAck) (40N-A-T-S-5858J-e-5a56d2336399940bec7d719acfe60323.bc)
  • InviteLinks (I-nviteL-inks.bc)
  • InviteLinkQuery (I-nviteL-inkQ-uery.bc)
  • Hash(InviteLink.class, String) (H-ash40I-nviteL-ink46class4432S-tring41.bc)
  • InviteLink (I-nviteL-ink.bc)
  • Route::Flash (R-oute5858F-lash.bc)
  • MessagePack::Lexer+ (M-essageP-ack5858L-exer43.bc)
  • Array(MessagePack::Token::ArrayT | MessagePack::Token::BoolT | MessagePack::Token::BytesT | MessagePack::Token::ExtT | MessagePack::Token::FloatT | MessagePack::Token::HashT | MessagePack::Token::IntT | MessagePack::Token::NullT | MessagePack::Token::StringT) (A-rray40M-essageP-d547f6b9caecffe6d1a876a1406f56b5.bc)
  • Armature::Form (A-rmature5858F-orm.bc)
  • MIME::Multipart::Parser (M-I-M-E-5858M-ultipart5858P-arser.bc)
  • HTTP::FormData::Part (H-T-T-P-5858F-ormD-ata5858P-art.bc)
  • HTTP::FormData (H-T-T-P-5858F-ormD-ata.bc)
  • IdentityQuery (I-dentityQ-uery.bc)
  • Hash(Identity.class, String) (H-ash40I-dentity46class4432S-tring41.bc)
  • Identity (I-dentity.bc)
  • CalendarProvider (C-alendarP-rovider.bc)
  • AccessTokenQuery (A-ccessT-okenQ-uery.bc)
  • Hash(AccessToken.class, String) (H-ash40A-ccessT-oken46class4432S-tring41.bc)
  • AccessToken (A-ccessT-oken.bc)
  • OAuth2::Client (O-A-uth25858C-lient.bc)
  • URI::Params::Builder (U-R-I-5858P-arams5858B-uilder.bc)
  • StaticArray(UInt16, 8) (S-taticA-rray40U-I-nt164432841.bc)
  • HTTP::Client::Response (H-T-T-P-5858C-lient5858R-esponse.bc)
  • OAuth2::AccessToken (O-A-uth25858A-ccessT-oken.bc)
  • Interro::UpdateOperation(AccessToken) (I-nterro5858U-pdateO-peration40A-ccessT-oken41.bc)
  • Array(Interro::Any | String | Time) (A-rray40I-nterro5-e8ee52f61e7fd25d60e960374c59ff16.bc)
  • Array(AccessToken) (A-rray40A-ccessT-oken41.bc)
  • InvitationQuery (I-nvitationQ-uery.bc)
  • Array(String | UUID) (A-rray40S-tring3212432U-U-I-D-41.bc)
  • Hash(Invitation.class, String) (H-ash40I-nvitation46class4432S-tring41.bc)
  • Invitation (I-nvitation.bc)
  • Google::calendar::V3::Events (G-oogle5858C-alendar5858V-35858E-vents.bc)
  • Google::calendar::V3::Attendee (G-oogle5858C-alendar5858V-35858A-ttendee.bc)
  • Array(Google::calendar::V3::Attendee) (A-rray40G-oogle5858C-alendar5858V-35858A-ttendee41.bc)
  • Google::calendar::V3::Timestamp (G-oogle5858C-alendar5858V-35858T-imestamp.bc)
  • Google::calendar::V3::Events::EventsInsertRequest (G-oogle5858C-alen-65e687fc3d1d2a64d8827f820eeef7ef.bc)
  • Google::calendar::V3::Date (G-oogle5858C-alendar5858V-35858D-ate.bc)
  • Google::calendar::V3::Attendee::ResponseStatus (G-oogle5858C-alen-e2b2caa92753d5559373dc82d9c6e4c2.bc)
  • Google::calendar::V3::Attendee::ConferenceData (G-oogle5858C-alen-d31b8106d8368a09dacaced6ae156b38.bc)
  • Google::calendar::V3::Attendee::ConferenceData::CreateRequest (G-oogle5858C-alen-52b2c50a02a3e065661078a422a8f6cc.bc)
  • Google::calendar::V3::Attendee::ConferenceSolutionKey (G-oogle5858C-alen-687907f0b1b5d4d1cf0c976be4210fb7.bc)
  • Google::calendar::V3::Attendee::ConferenceData::CreateRequest::Status (G-oogle5858C-alen-4b039b6a816fde25f3a2cc8986ed88a3.bc)
  • Array(Google::calendar::V3::Attendee::Entrypoint) (A-rray40G-oogle58-330d8e7c2f06f0b65bfff79c139f5263.bc)
  • Google::calendar::V3::Attendee::Entrypoint (G-oogle5858C-alen-ebf67f192d6f002d8303804b3439c5b0.bc)
  • Google::calendar::V3::Attendee::ConferenceSolution (G-oogle5858C-alen-ebfd2b21b2ecc609d0bfae2f98d5f40c.bc)
  • Google::calendar::V3::Event::Visibility (G-oogle5858C-alen-de2628b0e4caabbea051e8388f0c73dd.bc)
  • Google::calendar::V3::Event::Status (G-oogle5858C-alendar5858V-35858E-vent5858S-tatus.bc)
  • Google::calendar::V3::Event (G-oogle5858C-alendar5858V-35858E-vent.bc)
  • (Google::calendar::V3::Person | Nil) (40G-oogle5858C-al-ba47d21ab79643ee32c73ff5f67ebfd9.bc)
  • Google::calendar::V3::Person (G-oogle5858C-alendar5858V-35858P-erson.bc)
  • (Google::calendar::V3::Date | Google::calendar::V3::Timestamp) (40G-oogle5858C-al-91928c1d0224dd96abb8b6bec3407625.bc)
  • (Google::calendar::V3::Date | Google::calendar::V3::Timestamp | Nil) (40G-oogle5858C-al-5b0910a5cc2bf09379b34494a4c53ecd.bc)
  • (Array(Google::calendar::V3::Attendee) | Nil) (40A-rray40G-oogle-31c360a0ba60c3043e9f8b4a3e8275fb.bc)
  • (Google::calendar::V3::Attendee::ResponseStatus | Nil) (40G-oogle5858C-al-f01427328e016bc0e53a12aea091a0c1.bc)
  • (Google::calendar::V3::Attendee::ConferenceData | Nil) (40G-oogle5858C-al-c61fb7f82156979d6bc9e8a0d6c456d2.bc)
  • (Array(Google::calendar::V3::Attendee::Entrypoint) | Nil) (40A-rray40G-oogle-dc1d375ca1d6b7e2990f401c49c63235.bc)
  • (Google::calendar::V3::Attendee::ConferenceSolution | Nil) (40G-oogle5858C-al-0d8d15f8a56bcc3726f7fc173c01434f.bc)
  • (Google::calendar::V3::Event::ExtendedProperties | Nil) (40G-oogle5858C-al-1a5c6a78afb6c38a4960b8efb01a161d.bc)
  • Google::calendar::V3::Event::ExtendedProperties (G-oogle5858C-alen-1db0a38fa1ec4a19eeb48968c49d6fc0.bc)
  • (Google::calendar::V3::Event::Reminders | Nil) (40G-oogle5858C-al-fe3fa2031465ed154b38d0de0c1a86a5.bc)
  • Google::calendar::V3::Event::Reminders (G-oogle5858C-alen-c944fde0575c22d59e3effef878c0cfa.bc)
  • (Array(Google::calendar::V3::Event::Reminders::Override) | Nil) (40A-rray40G-oogle-7c07ea515ac65d918a403972ea30eaca.bc)
  • Array(Google::calendar::V3::Event::Reminders::Override) (A-rray40G-oogle58-1d7776824d8b00879fbcc3978266b916.bc)
  • Google::calendar::V3::Event::Reminders::Override (G-oogle5858C-alen-147726c504cfe5ce89b255cf3fa7e2df.bc)
  • (Google::calendar::V3::Event::EventType | Nil) (40G-oogle5858C-al-bfb52114d17ecf5a898b056ba9a97a69.bc)
  • Google::calendar::V3::Event::EventType (G-oogle5858C-alen-bae6d96f1648c46341b4b69f0394471a.bc)
  • Interro::UpdateOperation(Invitation) (I-nterro5858U-pdateO-peration40I-nvitation41.bc)
  • Array(Interro::Any | String) (A-rray40I-nterro5858A-ny3212432S-tring41.bc)
  • Array(Invitation) (A-rray40I-nvitation41.bc)
  • NotificationQuery (N-otificationQ-uery.bc)
  • Hash(Notification.class, String) (H-ash40N-otification46class4432S-tring41.bc)
  • Notification (N-otification.bc)
  • Armature::Session+ (A-rmature5858S-ession43.bc)
  • Array(UserAvailability) (A-rray40U-serA-vailability41.bc)
  • Hash(Time::DayOfWeek, Array(UserAvailability)) (H-ash40T-ime5858D-eb21e9afc9e7314521e9b2a6f343f51c.bc)
  • Array(Time::DayOfWeek) (A-rray40T-ime5858D-ayO-fW-eek41.bc)
  • Slice(Time::DayOfWeek) (S-lice40T-ime5858D-ayO-fW-eek41.bc)
  • GuestInvitations (G-uestI-nvitations.bc)
  • Armature::Cache::NATSStore::Entry(Google::calendar::V3::Event) (A-rmature5858C-ac-9be3692ef952add483413ff4a005ce4f.bc)
  • Armature::Cache::NATSStore::Entry(T) (A-rmature5858C-ac-afdb74c6e2b6815483d9d8a5616cc0d4.bc)
  • OAuthRoute (O-A-uthR-oute.bc)
  • Google::People::V1 (G-oogle5858P-eople5858V-1.bc)
  • Google::People::V1::GetPersonResponse (G-oogle5858P-eople5858V-15858G-etP-ersonR-esponse.bc)
  • Google::People::V1::GetPersonResponse::Metadata (G-oogle5858P-eopl-9449224ad0307b03fb3635aa72d3f601.bc)
  • Array(Google::People::V1::GetPersonResponse::Metadata::Source) (A-rray40G-oogle58-8cfe4aaad2b88e67724ebe689c49aaef.bc)
  • Google::People::V1::GetPersonResponse::Metadata::Profile (G-oogle5858P-eopl-8f35bb82fecf16dd8a39e7fcf697acee.bc)
  • Google::People::V1::GetPersonResponse::Metadata::DomainProfile (G-oogle5858P-eopl-beff49042e185f65fa4fb6dccf3049a9.bc)
  • (Array(Google::People::V1::GetPersonResponse::Name) | Nil) (40A-rray40G-oogle-f77990650981d6946c90b0821b8987c2.bc)
  • Array(Google::People::V1::GetPersonResponse::Name) (A-rray40G-oogle58-7043f8f2aec75c50fe9bb088efd83d57.bc)
  • Google::People::V1::GetPersonResponse::Name (G-oogle5858P-eopl-30fb81176c5872587f11324a0548f53f.bc)
  • Google::People::V1::GetPersonResponse::FieldMetadata (G-oogle5858P-eopl-36c461c66bc4628919a431d6e133050f.bc)
  • Google::People::V1::GetPersonResponse::FieldMetadata::Source (G-oogle5858P-eopl-cad2d9b6921558850abb2cf16b21cd78.bc)
  • (Array(Google::People::V1::GetPersonResponse::Photo) | Nil) (40A-rray40G-oogle-7eba9a140dd247b146e28522d600e7c1.bc)
  • Array(Google::People::V1::GetPersonResponse::Photo) (A-rray40G-oogle58-45de4e5128e30a997c849ce2b7219e0e.bc)
  • Google::People::V1::GetPersonResponse::Photo (G-oogle5858P-eopl-71cedc5c2248a8e5709a108ae67dbb2e.bc)
  • (Array(Google::People::V1::GetPersonResponse::EmailAddress) | Nil) (40A-rray40G-oogle-4e3f0163c3a15d98af9b4712bc270441.bc)
  • Array(Google::People::V1::GetPersonResponse::EmailAddress) (A-rray40G-oogle58-fc42d9d6e5454b8620a4d35fcbf18e36.bc)
  • Google::People::V1::GetPersonResponse::EmailAddress (G-oogle5858P-eopl-2d6e07dd0b64f0175a925b7a31602945.bc)
  • Stripe::Customers (S-tripe5858C-ustomers.bc)
  • Interro::Update(T) (I-nterro5858U-pdate40T-41.bc)
  • Interro::ConflictHandler(UpdateHandler) (I-nterro5858C-onflictH-andler40U-pdateH-andler41.bc)
  • Array(String | Time | Nil) (A-rray40S-tring3212432T-ime3212432N-il41.bc)
  • Microsoft::People (M-icrosoft5858P-eople.bc)
  • Microsoft::People::Person (M-icrosoft5858P-eople5858P-erson.bc)
  • Hash(String, MessagePack::Type) (H-ash40S-tring4432M-essageP-ack5858T-ype41.bc)
  • (Array(Microsoft::People::ScoredEmailAddress) | Nil) (40A-rray40M-icros-9f7f7463e2e7d1c03778a3d4452d1cf0.bc)
  • Array(Microsoft::People::ScoredEmailAddress) (A-rray40M-icrosof-5920a22193faed6edad5148cca0d9b33.bc)
  • Microsoft::People::ScoredEmailAddress (M-icrosoft5858P-eople5858S-coredE-mailA-ddress.bc)
  • (Array(Microsoft::People::Website) | Nil) (40A-rray40M-icros-1faa59c27f384524f9385cc0f8efe96d.bc)
  • Array(Microsoft::People::Website) (A-rray40M-icrosoft5858P-eople5858W-ebsite41.bc)
  • Microsoft::People::Website (M-icrosoft5858P-eople5858W-ebsite.bc)
  • (Microsoft::People::Website::Type | Nil) (40M-icrosoft5858P-fdd95a6257e5ff324f62403a26b08a32.bc)
  • Microsoft::People::Website::Type (M-icrosoft5858P-eople5858W-ebsite5858T-ype.bc)
  • Microsoft::Photo (M-icrosoft5858P-hoto.bc)
  • Microsoft::Photo::Photo (M-icrosoft5858P-hoto5858P-hoto.bc)
  • Stripe::Products (S-tripe5858P-roducts.bc)
  • Stripe::List(Stripe::Product) (S-tripe5858L-ist40S-tripe5858P-roduct41.bc)
  • Array(Stripe::Product) (A-rray40S-tripe5858P-roduct41.bc)
  • PrettyPrint (P-rettyP-rint.bc)
  • Deque(PrettyPrint::Breakable | PrettyPrint::Text) (D-eque40P-rettyP–0271f7a109cb224ca52b000340464313.bc)
  • Deque(PrettyPrint::Breakable) (D-eque40P-rettyP-rint5858B-reakable41.bc)
  • Array(PrettyPrint::Group) (A-rray40P-rettyP-rint5858G-roup41.bc)
  • Array(Array(PrettyPrint::Group)) (A-rray40A-rray40P-rettyP-rint5858G-roup4141.bc)
  • Calendars (C-alendars.bc)
  • CalendarSubscriptionQuery (C-alendarS-ubscriptionQ-uery.bc)
  • Interro::DynamicQuery(Tuple(String, CalendarProvider), CalendarSubscriptionQuery) (I-nterro5858D-yna-4a21bf48b3483687adb386fa23d03e2b.bc)
  • Array(Tuple(String, CalendarProvider)) (A-rray40T-uple40S-tring4432C-alendarP-rovider4141.bc)
  • Interro::DynamicQuery(Tuple(AccessToken, Identity), AccessTokenQuery) (I-nterro5858D-yna-6c22ea9027c5b7109ef12ebe1a2a6093.bc)
  • Array(Calendars::GoogleCalendar | Calendars::MicrosoftCalendar) (A-rray40C-alendar-536990d932a0f098c36eb840bbf19671.bc)
  • Armature::Cache::NATSStore::Entry(Calendars::GoogleCalendar | Calendars::MicrosoftCalendar) (A-rmature5858C-ac-d0147e0257ff9dd941b81428b661ace5.bc)
  • Calendars::GoogleCalendar (C-alendars5858G-oogleC-alendar.bc)
  • Array(Google::calendar::V3::CalendarList::Entry) (A-rray40G-oogle58-34c50e4208d2ddfff2e0f08aed006783.bc)
  • Google::calendar::V3::CalendarList::Entry (G-oogle5858C-alen-85da34a5d6060f5978bdd8e2b09ff74a.bc)
  • Calendars::MicrosoftCalendar (C-alendars5858M-icrosoftC-alendar.bc)
  • Array(Microsoft::Calendars::Calendar) (A-rray40M-icrosoft5858C-alendars5858C-alendar41.bc)
  • Microsoft::Calendars::Calendar (M-icrosoft5858C-alendars5858C-alendar.bc)
  • Hash(MessagePack::Type, MessagePack::Type) (H-ash40M-essageP–0261c9ff002f05c881fb5296086c2b1c.bc)
  • Microsoft::Calendars::EmailAddress (M-icrosoft5858C-alendars5858E-mailA-ddress.bc)
  • Array(Microsoft::Calendars::OnlineMeetingProvider) (A-rray40M-icrosof-1c4c3201a0c4b9db6c58c3233b3a27ea.bc)
  • Microsoft::Calendars::OnlineMeetingProvider (M-icrosoft5858C-a-3d458094e2637d35ac28bb4716717808.bc)
  • RefreshToken (R-efreshT-oken.bc)
  • Google::calendar::V3::CalendarList (G-oogle5858C-alendar5858V-35858C-alendarL-ist.bc)
  • Google::calendar::V3::CalendarList::CalendarListResponse (G-oogle5858C-alen-f1af508b440d1808dd069f4dc0fbe13a.bc)
  • Microsoft::Calendars (M-icrosoft5858C-alendars.bc)
  • Microsoft::Response(Array(Microsoft::Calendars::Calendar)) (M-icrosoft5858R-e-4b2c4b4a8de76a32272989677c83711b.bc)
  • Calendars::CalendarCollection (C-alendars5858C-alendarC-ollection.bc)
  • Calendars::CalendarDuration (C-alendars5858C-alendarD-uration.bc)
  • Channel(Tuple(Google::calendar::V3::Calendar | Microsoft::Calendars::Calendar | Nil, Array(Google::calendar::V3::Event) | Array(Microsoft::Calendars::Event))) (C-hannel40T-uple4-6838a95393af6600586dd7da01c31766.bc)
  • Deque(Tuple(Google::calendar::V3::Calendar | Microsoft::Calendars::Calendar | Nil, Array(Google::calendar::V3::Event) | Array(Microsoft::Calendars::Event))) (D-eque40T-uple40G-1451d7b99d58cfe61211430dd399df3b.bc)
  • Array(Google::calendar::V3::Event) (A-rray40G-oogle5858C-alendar5858V-35858E-vent41.bc)
  • Armature::Cache::NATSStore::Entry(Google::calendar::V3::Calendar | Microsoft::Calendars::Calendar) (A-rmature5858C-ac-0a3f718a8728e992e10f549e326bf985.bc)
  • Google::calendar::V3::Calendar (G-oogle5858C-alendar5858V-35858C-alendar.bc)
  • Google::calendar::V3::calendar::ConferenceProperties (G-oogle5858C-alen-29eb7439d4019a8262e61f59ee4c4118.bc)
  • Google::calendar::V3::Calendars (G-oogle5858C-alendar5858V-35858C-alendars.bc)
  • Armature::Cache::NATSStore::Entry(Array(Google::calendar::V3::Event) | Array(Microsoft::Calendars::Event)) (A-rmature5858C-ac-3b02ba44380f974fc863517ad06802eb.bc)
  • Array(Microsoft::Calendars::Event) (A-rray40M-icrosoft5858C-alendars5858E-vent41.bc)
  • Microsoft::Calendars::Event (M-icrosoft5858C-alendars5858E-vent.bc)
  • Microsoft::Calendars::Event::Timestamp (M-icrosoft5858C-alendars5858E-vent5858T-imestamp.bc)
  • Array(Microsoft::Calendars::Event::Attendee) (A-rray40M-icrosof-cf33652cb2316d5ccadd02534c929d0c.bc)
  • Microsoft::Calendars::Event::Attendee (M-icrosoft5858C-alendars5858E-vent5858A-ttendee.bc)
  • Microsoft::Calendars::Event::Body (M-icrosoft5858C-alendars5858E-vent5858B-ody.bc)
  • (Microsoft::Calendars::Event::Location | Nil) (40M-icrosoft5858C-9c6c39e67adbbee83a9f70a2a03c4684.bc)
  • Microsoft::Calendars::Event::Location (M-icrosoft5858C-alendars5858E-vent5858L-ocation.bc)
  • Microsoft::Calendars::Event::Location::Address (M-icrosoft5858C-a-45cfdda18e6e1114a27ce4b19b447a79.bc)
  • Microsoft::Calendars::Event::Location::Coordinates (M-icrosoft5858C-a-48af1e04fbe062d5286807a866cd8f3c.bc)
  • (Float64 | Nil) (40F-loat643212432N-il41.bc)
  • (Array(Microsoft::Calendars::Event::Location) | Nil) (40A-rray40M-icros-183a6769486a37887b9c58f810dd5ea8.bc)
  • Array(Microsoft::Calendars::Event::Location) (A-rray40M-icrosof-1bb36ec405d0edf7c63a51d426c14d46.bc)
  • (Microsoft::Calendars::OnlineMeeting | Nil) (40M-icrosoft5858C-e6a6c18895c9921ad2f70d03a564d7c6.bc)
  • Microsoft::Calendars::OnlineMeeting (M-icrosoft5858C-alendars5858O-nlineM-eeting.bc)
  • (Array(Microsoft::Calendars::Phone) | Nil) (40A-rray40M-icros-068a0390629e3c88b8a06f0125256b11.bc)
  • Array(Microsoft::Calendars::Phone) (A-rray40M-icrosoft5858C-alendars5858P-hone41.bc)
  • Microsoft::Calendars::Phone (M-icrosoft5858C-alendars5858P-hone.bc)
  • Microsoft::Calendars::phone::Type (M-icrosoft5858C-alendars5858P-hone5858T-ype.bc)
  • (Microsoft::Calendars::Event::PatternedRecurrence | Nil) (40M-icrosoft5858C-cc71cdc98cb63f35175bff7a9026e7fa.bc)
  • Microsoft::Calendars::Event::PatternedRecurrence (M-icrosoft5858C-a-269eb2a525e3d12c6183d457149841b0.bc)
  • Microsoft::Calendars::Event::RecurrencePattern (M-icrosoft5858C-a-9eb6e8981e04c5a8df215865c7167f3a.bc)
  • Microsoft::Calendars::Event::RecurrencePattern::WeekIndex (M-icrosoft5858C-a-705dc412c71edf45266b1e2040843d03.bc)
  • Microsoft::Calendars::Event::RecurrencePattern::Type (M-icrosoft5858C-a-a050cc63c90f166108e4792a6a45fe36.bc)
  • Microsoft::Calendars::Event::RecurrenceRange (M-icrosoft5858C-a-d840122c014dd05e66e5efee6fd9a643.bc)
  • Microsoft::Calendars::Event::RecurrenceRange::Type (M-icrosoft5858C-a-8938ce058f076246e0193d54dd0f8048.bc)
  • Microsoft::Calendars::Event::ResponseStatus (M-icrosoft5858C-a-d372798269afa62652bae5fa7a7bef80.bc)
  • Google::calendar::V3::EventsListResponse (G-oogle5858C-alen-aa0c23edf6c0f9d0e925f67281241097.bc)
  • (Array(JSON::Any) | Nil) (40A-rray40J-S-O-N-5858A-ny413212432N-il41.bc)
  • Microsoft::Response(Array(Microsoft::Calendars::Event)) (M-icrosoft5858R-e-abd3ae59538991803180bbb1e81f4f75.bc)
  • Channel::SelectContext(Tuple(Google::calendar::V3::Calendar | Microsoft::Calendars::Calendar | Nil, Array(Google::calendar::V3::Event) | Array(Microsoft::Calendars::Event))) (C-hannel5858S-ele-996c91b37080899de00d1186a5be953a.bc)
  • Array(Google::calendar::V3::Calendar | Microsoft::Calendars::Calendar) (A-rray40G-oogle58-8eed6a29f8ede349d43a73117d2b7e27.bc)
  • Slice(Tuple(Google::calendar::V3::Event | Microsoft::Calendars::Event, Time)) (S-lice40T-uple40G-22eaf29f8d36404a1a33dfa53248738c.bc)
  • Calendars::Date (C-alendars5858D-ate.bc)
  • Steppable::StepIterator(T, L, B) (S-teppable5858S-tepI-terator40T-4432L-4432B-41.bc)
  • Steppable::StepIterator(Time, Time, Time::Span) (S-teppable5858S-t-d5cbc982674fab6f88df46ff9887a2b0.bc)
  • Iterator::MapIterator(Steppable::StepIterator(Time, Time, Time::Span), Time, Calendars::Date) (I-terator5858M-ap-ca231f5760ec06e57dbd9c5034380d98.bc)
  • Array(Calendars::Date) (A-rray40C-alendars5858D-ate41.bc)
  • Array(Calendars::Date | Nil) (A-rray40C-alendars5858D-ate3212432N-il41.bc)
  • Hash(CalendarSubscription.class, String) (H-ash40C-alendarS-ubscription46class4432S-tring41.bc)
  • CalendarSubscription (C-alendarS-ubscription.bc)
  • Settings (S-ettings.bc)
  • Interro::DynamicQuery(Tuple(String, String), SettingQuery) (I-nterro5858D-yna-aac1430e168541b1dc903d0f8becb50e.bc)
  • Array(InviteLink) (A-rray40I-nviteL-ink41.bc)
  • Select(T) (S-elect40T-41.bc)
  • Array(Select::Option) (A-rray40S-elect5858O-ption41.bc)
  • Select::Option (S-elect5858O-ption.bc)
  • SettingQuery::Update (S-ettingQ-uery5858U-pdate.bc)
  • ManageInviteLinks (M-anageI-nviteL-inks.bc)
  • Interro::DynamicQuery(Tuple(InviteLink, Identity), InviteLinkQuery) (I-nterro5858D-yna-40da513cb80419bc7175eafc93d36d25.bc)
  • Array(Validations::Result::Error) (A-rray40V-alidations5858R-esult5858E-rror41.bc)
  • Slice(Tuple(Validations::Result::Error, String)) (S-lice40T-uple40V-4b824cc8b69803163e2a194d3795f49a.bc)
  • Input (I-nput.bc)
  • Input::Type (I-nput5858T-ype.bc)
  • Input::Autocorrect (I-nput5858A-utocorrect.bc)
  • Armature::Cache::NATSStore::Entry(Array(Select::Option)) (A-rmature5858C-ac-e30c124b996de980d28eef6e0dad32a6.bc)
  • Slice(Tuple(Select::Option, String)) (S-lice40T-uple40S-elect5858O-ption4432S-tring4141.bc)
  • Array(Tuple(String, String)) (A-rray40T-uple40S-tring4432S-tring4141.bc)
  • Interro::UpdateOperation(InviteLink) (I-nterro5858U-pdateO-peration40I-nviteL-ink41.bc)
  • Notifications (N-otifications.bc)
  • Interro::QueryBuilder::OrderByDirection (I-nterro5858Q-ueryB-uilder5858O-rderB-yD-irection.bc)
  • Range(Nil, Time::Span) (R-ange40N-il4432T-ime5858S-pan41.bc)
  • Interro::UpdateOperation(Notification) (I-nterro5858U-pdateO-peration40N-otification41.bc)
  • Array(Interro::Any | Time) (A-rray40I-nterro5858A-ny3212432T-ime41.bc)
  • Array(Notification) (A-rray40N-otification41.bc)
  • HTTP::WebSocket (H-T-T-P-5858W-ebS-ocket.bc)
  • HTTP::WebSocket::CloseCode (H-T-T-P-5858W-ebS-ocket5858C-loseC-ode.bc)
  • MIME (M-I-M-E-.bc)
  • Array(Range(Int64, Int64)) (A-rray40R-ange40I-nt644432I-nt644141.bc)
  • MIME::Multipart::Builder (M-I-M-E-5858M-ultipart5858B-uilder.bc)
  • String::Formatter(Tuple(Int32, Float64)) (S-tring5858F-orma-d38cd524ba9a8946bbf0c92b79665e18.bc)
  • String::Formatter::Mode (S-tring5858F-ormatter5858M-ode.bc)
  • String::Formatter::Flags (S-tring5858F-ormatter5858F-lags.bc)
  • Range(Nil, Nil) (R-ange40N-il4432N-il41.bc)
  • String::Formatter(Tuple(Float64)) (S-tring5858F-ormatter40T-uple40F-loat644141.bc)
  • Bugsnag::Exception (B-ugsnag5858E-xception.bc)
  • Array(Bugsnag::StackFrame) (A-rray40B-ugsnag5858S-tackF-rame41.bc)
  • Bugsnag::StackFrame (B-ugsnag5858S-tackF-rame.bc)
  • Hash(Int32, String) (H-ash40I-nt324432S-tring41.bc)
  • Bugsnag::Request (B-ugsnag5858R-equest.bc)
  • Bugsnag::Event (B-ugsnag5858E-vent.bc)
  • Bugsnag::Client (B-ugsnag5858C-lient.bc)
  • Bugsnag::Event::Severity (B-ugsnag5858E-vent5858S-everity.bc)
  • Bugsnag::App::BinaryArch (B-ugsnag5858A-pp5858B-inaryA-rch.bc)
  • NATS::JetStream::ConsumerConfig::AckPolicy (N-A-T-S-5858J-etS-cbfacaa1d6e848c5837ddeb299e5b57c.bc)
  • NATS::JetStream::ConsumerConfig::DeliverPolicy (N-A-T-S-5858J-etS-a0d12c494d60319b1703c53f168123ea.bc)
  • NATS::JetStream::ConsumerConfig::ReplayPolicy (N-A-T-S-5858J-etS-f049f8571227f1316933f67944a4bd30.bc)

real 0m6.807s
user 0m10.587s
sys 0m1.113s

The only thing that changed was one Armature::Route.route call inside my Web#call method. It makes perfect sense for those modules to be recompiled, but it’s not obvious why hundreds of other modules including the Google, Microsoft, NATS, Bugsnag, and Stripe shards would need to be.

So I’m wondering, is it feasible to optimistically reuse cached compilations and only fall back to recompiling if the cached types would fail a type check? In the example of the Moo mixin, if nobody ever calls Foo.new(another_moo) or Foo.new(generic_moo), are there downsides to reusing the compilation of Foo.new that only includes MyMoo.{bc,o}?

5 Likes

Would it be an idea, that if you want to compile incremental, declaring variables is mandatory and for normal compilation it is not?

The answer is here: Incremental compilation for Crystal - Part 1 - DEV Community

1 Like

The code I added invokes String#to_s(io : IO), and since I’m already doing I/O elsewhere in the app, it doesn’t change what methods are compiled — String#to_s(io : IO) would already have been compiled. Is it because the dependency graph changes, since now that method being invoked by a new caller? Or is it because now io.cr in the stdlib depends on this route, so now everything that depends on io.cr also has to be recompiled, including structs that are just JSON::Serializable with getters? Or some secret third option?

Does this also mean that, with the current compiler implementation, it’s more performant not to put multiple object definitions in a single file to keep the dependency graph more granular?

  1. A new compiler flag that would fail fast whenever it encountered a new signature that was missing typing information (rather than having multiple “tiers” of compilation speed, I’d prefer just to have a one-and-done approach).

This seems like the best approach to me. A stricter mode that just flags anything that can’t be immediately inferred. Requires no breaking changes and allows you to have simple type-free code when you want, but at the same time takes full advantage of all the typing when people like @MistressRemilia add them in.

1 Like

It always seems impossible until it’s done. - Nelson Mandela

1 Like

I’m not sure how well this would play out with libraries since they’re compiled each time unless there was a hard break in the compiler regarding backwards compatibility. If your dependencies are a mix of ones with complete type annotations and ones without complete type annotations, it wouldn’t compile. And those without may be out of your control.

I sometimes use the interpreter when I have to check something by hand, but not often. Usually I just make a temporary Crystal file and do crystal run, which is fast enough. For my actual projects, it’s often just not possible to use it. Most of my projects crash it.

3 Likes

If it’s not reported in the issue tracker, can you do it :pray: ? Otherwise ignore this message.

1 Like

Well I know I’m in over my head here and I really appreciated reading @asterite’s write up on dev.to and here as well. I also appreciate getting @beta-ziliani’s update on the near future of Crystal.

I also love Crystal! And I actually don’t mind a possible future where it is good at making microservices. The old Unix philosophy has proved true for me again and again (Write programs that do one thing and do it well. Write new programs instead of bloating old ones with new features. Pass text streams instead of sharing memory.). So if we have a language that discourages you from violating that is it so bad? Maybe Crystal becomes the language that specializes in this. That’s ok! I agree that sticking to the Crystal vision is a worthy goal and I support it :slight_smile:

That all said, I am curious about the trade space / spectrum side of this. How much of the Crystal spirit do we lose if we just require abstract methods/classes to be strongly typed? How much IDE/LSP/DevX support do we gain?

@asterite seems to argue here that it’s all or nothing, not a spectrum or a set of tradeoffs. I’m not qualified to comment, but if his assessment is limited to compile-time speeds I wonder if there are other benefits re developer experience worth considering.

All in all, just wanted to say that I love the community, this discussion, and the language. I’m ok with it staying the course. I’m also ok if we need to break something and go 2.x because someone figured out a way to improve our dev-x by making type inference a little dumber (or moving to explicit require/import … which I just kinda want anyways :stuck_out_tongue: )

4 Likes

6 posts were split to a new topic: Room Temperature Superconductors

55 and even 30 seconds for 7000 lines seems a lot (without --release i assume?). One of my projects has 5000 lines and compiles in 4 seconds (–release takes 30). Most of the time is spent in the codegen phase. If i use --no-codegen it takes 1.5 seconds (even if i change lines in the code). The project uses crsfml, crystal-chipmunk and crystal-open-simplex-noise, so only a few dependencies. Spec: Linux Manjaro, Intel i7-6700K CPU 4.00GH, 46GB RAM, SSDs. What does --stats --progress show for your project?

Yeah, I’ve always noticed that the codegen (bc+obj) phase takes the longest. That’s where LLVM compiles the IR into byte/object code.

[alexa@lain benben]$ CRYSTAL_OPTS=--stats rake
=== Fully Optimized Build ===
shards build -p -Dpreview_mt --release --no-debug -Dyunosynth_wd40
Dependencies are satisfied
Building: benben
Parse:                             00:00:00.000173638 (   1.02MB)
Monkey patching the ZStandard bindings to fix a memory leak
Semantic (top level):              00:00:00.586158087 ( 171.49MB)
Semantic (new):                    00:00:00.002499083 ( 171.49MB)
Semantic (type declarations):      00:00:00.042015682 ( 187.49MB)
Semantic (abstract def check):     00:00:00.076894181 ( 187.49MB)
Semantic (restrictions augmenter): 00:00:00.010981664 ( 187.49MB)
Semantic (ivars initializers):     00:00:00.105040268 ( 251.49MB)
Semantic (cvars initializers):     00:00:00.010272253 ( 251.49MB)
Semantic (main):                   00:00:01.107068908 ( 507.67MB)
Semantic (cleanup):                00:00:00.000920854 ( 507.67MB)
Semantic (recursive struct check): 00:00:00.001233433 ( 507.67MB)
Codegen (crystal):                 00:00:01.604538998 ( 571.92MB)
Codegen (bc+obj):                  00:01:01.061826937 ( 571.92MB)
Codegen (linking):                 00:00:00.856938455 ( 571.92MB)

Codegen (bc+obj):
 - no previous .o files were reused
strip --strip-unneeded bin/benben
rst2man man/benben.1.rst > man/benben.1
gzip -f -9 -k man/benben.1
[alexa@lain benben]$

This is about 48k LOC. Slackware Linux, Core i9-10850K, 64GB RAM, over an NFS mount.

One thing I’m curious about is if adding on type annotations everywhere speeds up compile times. Like if the code doesn’t have a lot of type information, does it take longer to compile?

1 Like

How long does it take without --release? And does the LOC include the shards required by the project? Also, since only the codegen phase seems to be slow, while the semantic phase is quite fast, even for 48K LOC, this should make LSP stuff quite usable, or do i miss something here?

[alexa@lain benben]$ CRYSTAL_OPTS=--stats rake benben[debug]
=== Debug Build ===
shards build -p -Dpreview_mt --debug
Dependencies are satisfied
Building: benben
Parse:                             00:00:00.000178054 (   1.02MB)
Monkey patching the ZStandard bindings to fix a memory leak
Semantic (top level):              00:00:00.552095177 ( 171.49MB)
Semantic (new):                    00:00:00.002389812 ( 171.49MB)
Semantic (type declarations):      00:00:00.040912396 ( 187.49MB)
Semantic (abstract def check):     00:00:00.078602613 ( 187.49MB)
Semantic (restrictions augmenter): 00:00:00.011613046 ( 187.49MB)
Semantic (ivars initializers):     00:00:00.106903262 ( 251.49MB)
Semantic (cvars initializers):     00:00:00.010053685 ( 251.49MB)
Semantic (main):                   00:00:01.128705456 ( 507.67MB)
Semantic (cleanup):                00:00:00.001048599 ( 507.67MB)
Semantic (recursive struct check): 00:00:00.001374485 ( 507.67MB)
Codegen (crystal):                 00:00:02.635968092 ( 651.92MB)
Codegen (bc+obj):                  00:00:02.797098010 ( 651.92MB)
Codegen (linking):                 00:00:01.663105002 ( 651.92MB)

Codegen (bc+obj):
 - no previous .o files were reused
[alexa@lain benben]$

About seven seconds total without --release.

Yes, the LOC includes the shards since they get recompiled. There are eight dependencies, seven of which are written and maintained by me (the eighth is zstandard bindings). All of those dependencies include type annotations all over the place.

This is exactly what I was wondering earlier. Would the LSP invoke the actual compiler? Or does it just use a subset of it internally? I know what LSPs do, because I’ve used them in the past, but I stopped using them because I never really liked them (save for the pre-LSP-but-still-LSP-like Slime mode for Lisp).

1 Like

How do you compile your example in Lucky? Do you use the --release flag? Can you show the compilation with --stats --progress? It might also be possible that the macros used in the framework slow the compilation down.

I can’t speak on the community side of things, but in terms of tooling and LSP support this should help greatly. I’ve posted part of this in the Discord server, but it’s likely that the language server will have to force users to use explicit typing if they want contextual type information due to the complexities of type inference. If this becomes the standard in Crystal then that would make implementation much easier.

1 Like

There are some qualifier to those numbers, yes :slight_smile:

  • I develop on a potato (Intel(R) Core™ i7-8565U CPU @ 1.80GHz, 16GB RAM, Linux Mint 20.3, HD)
  • The full LOC, including libs, excluding development dependencies only, is ~24.7k
  • I abuse macros a lot in this project, which does a non-trivial amount of code generation
  • Non --release build times, correct. Those take a few minutes

Running the --stats --progress I get:

Parse:                             00:00:00.000034170 (   0.76MB)
Semantic (top level):              00:00:01.714205539 ( 346.28MB)
Semantic (new):                    00:00:00.004374415 ( 346.28MB)
Semantic (type declarations):      00:00:00.065950781 ( 362.28MB)
Semantic (abstract def check):     00:00:00.037417883 ( 378.28MB)
Semantic (restrictions augmenter): 00:00:00.011570771 ( 394.28MB)
Semantic (ivars initializers):     00:00:00.905395270 ( 458.34MB)
Semantic (cvars initializers):     00:00:00.016142508 ( 458.34MB)
Semantic (main):                   00:00:05.210358353 ( 890.71MB)
Semantic (cleanup):                00:00:00.001436360 ( 890.71MB)
Semantic (recursive struct check): 00:00:00.002808831 ( 890.71MB)
Codegen (crystal):                 00:00:09.592502330 (1148.21MB)
Codegen (bc+obj):                  00:00:01.851572238 (1148.21MB)
Codegen (linking):                 00:00:01.951206458 (1148.21MB)

Codegen (bc+obj):
 - 2100/2101 .o files were reused

This build took only 22 seconds :D

1 Like

I want to share a short article written in Japanese.

On February 25, 2023, there was an online event celebrating Ruby’s 30th anniversary. During this event, Matsumoto Yukihiro talked about his dream of a “Static Compiler for Ruby.”

His idea is to make a compiler with these features:

  • Abstract Interpretation
  • Profile Guided Type Inference
  • Interactive Annotation
  • Descriptive Type

The article also talks a bit about Crystal (but it’s not in a very positive context). :slight_smile:

In the world of compiled languages like Ruby, there’s something called “Crystal,” but it goes about things a bit differently.

Crystal sticks to the more traditional static types whenever it can and uses type inference. Initially, Crystal’s compiler was actually written in Ruby and aimed to be compatible. However, as time went on, it branched out and became its own separate language.

I’m thinking about whether it’s possible to create a compiled language without needing to explicitly declare types, taking a different approach from that.

(Translated by ChatGPT)

In the article, Matz predicts that in the future, we might see dynamic programming languages regain popularity as type inference gets better. Others in the Ruby core team probably share this idea. In any case, Ruby has chosen not to include types within the code.

I doubt that Matz will actually create a “Static Compiler for Ruby.” He was simply discussing his dream. If someone reads the article expecting that such a compiler will actually be introduced, they might end up disappointed.

I thought this article was a bit interesting, so I wanted to share.

3 Likes

Just share my viewpoint here.

  • Crystal was never used by a big company.
  • The amount of core developers (especially, full-time) is small, in this form, when newcomer ask questions, probably need several days to get the answer, because no one dedicated for this, i feel like the core members really don’t have time for this.
  • Founders of this language all in a very low activity status, as said by the last one:

(I don’t know why, but, i guess it’s probably not all about the money)

  • But i believe developing for this language does really require more more money, more attention.

Instead of talking about not having time for these features, need do more research, how about do something making Crystal acceptable to larger companies? bring the founders back? make community members more willing to get involved?

Refer to this:

1 Like