Numerous language specialists accept that the normal dialect an individual talks influences how they think. Does the same concept apply to computer dialects?
Software engineers who are working on different sorts of programming languages regularly come up with profoundly diverse solutions to issues. As a more extraordinary case, computer researchers dispensed with the
goto statement to encourage more organized programs. This is the same way the Flutter team has thought of when they picked up Dart. After evaluating more than 12 programming languages, they chose Dart because it matched with the way they planned to build the user interfaces (UI).
The code journey from compilation to execution
Historically, computer languages have been divided into two groups:
- Static languages where variables are well defined and statically typed at compile time (e.g., Java(Without Reflection), C or C++ ).
Static languages were typically compiled to produce native machine code (or assembly code) programs for the target machine, which at run time were executed directly by the hardware. Dynamic languages were executed by a middleware (Usually an interpreter) without producing machine language code.
Undoubtedly, things eventually became much more complicated. The concept of a virtual machine (VM) became popular, which is really just an advanced interpreter that mimics a hardware machine in software. A virtual machine makes it easier to port a language to new hardware platforms. In this case, the input language of a VM is often an intermediate language. For example, a programming language (such as Java) is compiled into a intermediate language (bytecode) and then executed on a Java Virtual Machine known as JVM .
In addition, there are now just-in-time (JIT) compilers. A JIT compiler runs during the execution of the program, compiling on the fly. The original compilers that execute during the build process of the program (before runtime) are now called ahead-of-time (AOT) compilers.
Generally, only static languages are compliant with AOT compilation into native machine code because machine languages typically need to know the type of data, and in dynamic languages the type is not fixed ahead of time. Consequently, dynamic languages are typically interpreted or JIT compiled.
When AOT compilation is done during development, it invariably results in much slower development cycles (the time between making a change to a program and being able to execute the program to see the result of the change). But AOT compilation results in programs that can execute more predictably and without pausing for analysis and compilation at runtime. AOT compiled programs also start executing faster (because they have already been compiled).
Conversely, JIT compilation provides much faster development cycles, but can result in slower or jerkier execution. In particular, JIT compilers have slower startup times, because when the program starts running the JIT compiler has to do analysis and compilation before the code can be executed. Studies have shown that many people will abandon an app if it takes more than a few seconds to start executing.
So after all, wouldn’t it be awesome to combine the advantages of both AOT and JIT compilation?
Compiling and executing Dart
Dart is one of very few languages that is well suited to being compiled both AOT and JIT. Supporting both kinds of compilation provides significant advantages to Dart and (especially) Flutter.
JIT compilation is used during development, using a compiler that is especially fast. Then, when an app is ready for release, it is compiled AOT. Consequently, with the help of advanced tooling and compilers, Dart can deliver the best of both worlds: extremely fast development cycles, and fast execution and startup times.
Finally, Dart also provides a standalone VM that uses the Dart language itself as its intermediate language (essentially acting like an interpreter).
Dart can be efficiently compiled AOT or JIT, interpreted, or transpiled into other languages. Not only is Dart compilation and execution unusually flexible, it is especially fast.
Render & Animate jank-less
By running your apps on 60 fps, Dart doesn’t only guarantee a fast app but it secures a smooth app which is even better. Even a super fast animation will look bad if it is jerky. However, preventing jank can be difficult because there are so many different causes. Dart has a number of features to avoid many of the common things that cause jank.
Of course, (like any language) it is still possible to write a janky app in Flutter; Dart helps by being more predictable and giving the developer more control over the smoothness of their app, making it easier to provide the best user experience possible, bar none.
AOT burns the “bridge”
Note: even compiled code may need an interface to talk to platform code, and this can also be called a bridge, but it is typically orders of magnitude faster than the bridge required by a dynamic language. In addition, because Dart allows things like widgets to be moved into the app, the need to go over a bridge is reduced.
Concurrency and Shared Resources
Race conditions are a double whammy because they can cause serious bugs, including crashing your app and causing data to be lost, and they are particularly difficult to find and fix because they depend on the relative timing of independent threads. It is all too common for race conditions to stop manifesting themselves when you run the app in a debugger.
The typical way to fix a race condition is to protect the shared resource using a lock that prevents other threads from executing, but locks themselves can cause jank, or even more serious problems including deadlock and starvation.
Not to mention that if the developer forgets to yield control, this can delay other code from executing. However, forgetting to yield is usually much easier to find and fix than forgetting to lock because race conditions are difficult to find.
Memory Allocation and Garbage Collection
Dart uses an advanced generational garbage collection and allocation scheme, which is particularly fast for allocating many short-lived objects (perfect for reactive user interfaces like Flutter that rebuild the immutable view tree for every frame). Dart can allocate an object with a single pointer bump (no lock required). Once again, this results in smooth scrolling and animation, without jank.