Getting Started with Rust
https://itmagination.medium.com/rust-the-perfect-language-for-blockchain-development-e8f4b39d892d

Getting Started with Rust

After watching a lot of Rusty videos, and doing Hello World in Rust, I finally started a real project: Comparing Files.

While learning .Net, I wrote a program to search for duplicate files on the file system, including a Graphical User Interface. It worked pretty well.

Later, wile learning Scala, I wrote some code to find duplicate files on my computer, but I never got around to implementing a GUI. This was done after completing the Functional Programming Principles in Scala from Coursera. Naturally, the code was all based on functional programming with non-mutable data structures, and the end result was very satisfying, although the code was very hard to read. Most notably, I could convert the code to parallel by changing one line of code, adding the ".par" method in a critical place.

However, one aspect of the code, I programmed in Java, to make it more portable, the code to compare the equality of two files. After a lot of experimentation, I found that using Memory Mapped Files, my code ran four times faster for large files than the Apache standard library, but there a lot of tricks to getting Java to behave.

Rust

I started to implement the same basic services in Rust, and I have been delightfully surprised.

  1. I started the project via IntelliJ IDEA, as a simple Rust project. This was way easier than I expected, as often getting started in new tools can be very painful.
  2. I started as a simple Rust library, and the template code was simple, with unit tests provide. I ran the tests, and everything just worked.
  3. I started expanding the code, and quickly realized I needed to learn how traits work in Rust, as the best way to deal with polymorphism. Rust is not like Java, Scala, Kotlin, C#, etc. But, that's okay, this old dog can still learn new tricks.
  4. With Rust, it is important to spit out the pacifier we have been suckling on with Java-like languages, and other languages, and learn to unlearn. Rust has very good reasons for the way things are done, because as nice as Java et al is, it got a lot of things wrong: null pointers, exceptions, etc. Not to say that garbage collection is wrong, but there are many applications where garbage collection causes a frustrating user experience in terms of latency.
  5. The Rust compiler is very good a explaining things, and directing us to success. The documentation is exceptionally good. My Scala experience is the antithesis of this.
  6. The GitHub Copilot integration with IntellJ IDEA is also pretty good, which really increased my productivity, especially in learning the language.
  7. I have been programming since 1970, and this has been one of the best experiences I have had putting a new programming language into practice.

Code

use std::fs::File;
use std::io::Read;

trait Equal {
    fn equal(&self, other: &Self) -> bool;
}

impl Equal for usize {
    fn equal(&self, other: &Self) -> bool {
        self == other
    }
}

/// # Compare two files by their content
///
/// Do this efficiently by comparing the file size first, then the content. There are still some
/// efficiency improvements that can be made, but this is a good start.
///
/// TODO Diagnostics are none, just a boolean result.
impl Equal for str {
    fn equal(&self, other: &Self) -> bool {
        match File::open(self) {
            Ok(mut file1) => match File::open(other) {
                Ok(mut file2) => {
                    match file1.metadata() {
                        Ok(metadata1) => {
                            match file2.metadata() {
                                Ok(metadata2) => if metadata1.len() == metadata2.len() {
                                    let mut buffer1 = Vec::with_capacity(metadata1.len() as usize);
                                    let mut buffer2 = Vec::with_capacity(metadata2.len() as usize);
                                    match file1.read_to_end(&mut buffer1) {
                                        Ok(_) => {
                                            match file2.read_to_end(&mut buffer2) {
                                                Ok(_)  => buffer1 == buffer2,
                                                Err(_) => false
                                            }
                                        }
                                        Err(_) => false
                                    }
                                } else {
                                    false
                                }
                                Err(_) => false
                            }
                        }
                        Err(_) => false
                    }
                }
                Err(_) => false,
            }
            Err(_) => false,
        }
    }
}
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let result = Equal::equal(&2, &2);
        assert_eq!(result, true);

        let result = Equal::equal("Cargo.toml", "Cargo.toml");
        assert_eq!(result, true);
    }
}        

Yes, this code looks like an ugly duckling for now because it has no diagnostics, it returns true or false, where any errors just return false. But, it was unbelievably easy to get the code to this point, a Walking Skeleton as a Proof of Concept, that is easy to work with.

Next Steps

  • Diagnostics. Instead of just returning false, implement a decent diagnostic framework based on Rust's Result type.
  • Add performance tests, and compare the speed with the equivalent Java code.
  • Use Memory Mapped Files, like the Java code, and compare performance.
  • Consider the use of io_uring on Linux and kqueue on FreeBSD/macOS. These APIs are the ultimate in high-performance File I/O, possibly faster than Memory Mapped Files

  • Add logging to the library.
  • Learn Rust/Tokio, to leverage concurrency and parallelism for faster comparisons on the file system. Having learned Java 21 Virtual Threads and Structured Concurrency, it will be interested to see how this is done in Rust. Already, it looks pretty different, but may have the same capabilities with Tokio Green Threads.

  • This application, Finding Duplicate Files, is a perfect systems programming fit.
  • The original application had a GUI, so I may explore what that looks like in Rust.

Conclusions

The more I learn Rust, the more I play with it, the more impressed I am.

I really don't like the look of Rust code, too many short names and chicken track characters, looks too much like C and C++. But, I am willing to overlook that for now while I am trying to grok Rust.

What I can say for sure is: if your company, your enterprise, is not learning Rust, all of your competition will have a compelling advantage over you.

Scott Ralph

AI/ML Contractor - Machine Learning, Data Science, ML Pipeline Architecture

11 个月

I'm still flummoxed. It's C with safety? Not Scala or exciting. Is it just very in-demand?

回复

要查看或添加评论,请登录

Eric Kolotyluk的更多文章

  • Iterators Make Sense in Rust

    Iterators Make Sense in Rust

    Interface Iterator has been in the Java standard library since version 1.2, December 8, 1998.

  • Going Further With Rust

    Going Further With Rust

    After writing Getting Started With Rust, the adventure got more interesting, and the resulting code was simplified to…

  • A Rusty Web Assembly Architecture

    A Rusty Web Assembly Architecture

    When I learned Java and Web Applets I could not understand why Applets failed as a technology, and I resented the fact…

  • Weird Rust

    Weird Rust

    The only Rust program I have written is "Hello World!" I have been watching many YouTube videos, but this resonated…

  • AI Idiocracy

    AI Idiocracy

    In the movie "Idiocracy" the hero wakes up in the future where everyone is stupid..

  • Dance Monkey Dance

    Dance Monkey Dance

    I had a job interview today that generally went quite well until the interviewer invoked the "Dance Monkey Dance"…

  • Arc Browser First Impressions

    Arc Browser First Impressions

    While watching I was impressed enough to try out this browser I had never heard of before. As a loyal Firefox user, it…

    1 条评论
  • Why RISC Five?

    Why RISC Five?

    The Genius of RISC-V Microprocessors is a highly technical presentation of RISC-V processors, so I am breaking it down…

  • Ten Years of MacBook Pro

    Ten Years of MacBook Pro

    I recently received my new M3 Max MacBook Pro to replace my 2013 Intel MacBook Pro. I will spare you the usual…

    2 条评论
  • Teamwork in the Modern Age

    Teamwork in the Modern Age

    I have been doing couple's dancing since 1997; to say the least, it’s teamwork. Sure, there are generally only two…

    2 条评论

社区洞察

其他会员也浏览了