• Go vs Rust:文件上传性能比较


    img

    在本文中,主要测试并比较了Go—Gin和Rust—Actix之间的多部分文件上传性能。

    设置

    所有测试都在配备16G内存的 MacBook Pro M1 上执行。

    软件版本为:

    • Go v1.20.5
    • Rust v1.70.0

    测试工具是一个基于 libcurl 并使用标准线程的自定义工具,能够发送多部分请求。

    资产目录中有 100,000 个文件。每个文件的大小都是确切的 100K。这些文件数量在测试工作线程之间进行分配。同一个文件不会一遍又一遍地上传。工作线程会循环处理分配给它们的文件。一旦它们处理完所有分配的文件,它们就会回到第一个文件重新开始。

    每个请求携带两个文件作为多部分请求体。请求的头部和体部大致如下:

    // -- Headers
    
    {
      "content-length": "205150",
      "content-type": "multipart/form-data; boundary=------------------------3f6a15690b315b91",
    }
    
    // -- Body
    
    --------------------------3f6a15690b315b91
    Content-Disposition: form-data; name="files"; filename="45469"
    Content-Type: application/octet-stream
    
    <>
    --------------------------3f6a15690b315b91
    Content-Disposition: form-data; name="files"; filename="42102"
    Content-Type: application/octet-stream
    
    <>
    --------------------------3f6a15690b315b91--
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    代码

    Go

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"github.com/jaevor/go-nanoid"
    )
    
    func main() {
    	dst := "/Users/mayankc/Work/source/perfComparisons/uploads/"
    	canonicID, err := nanoid.Standard(21)
    	if err != nil {
    		panic(err)
    	}
    
    	router := gin.New()
    	router.POST("/upload", func(c *gin.Context) {
    		form, _ := c.MultipartForm()
    		files := form.File["files"]
    
    		for _, file := range files {
    			c.SaveUploadedFile(file, dst+canonicID())
    		}
    		c.Writer.WriteHeader(201)
    	})
    	router.Run(":3000")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    Rust

    use actix_multipart::{
        form::{
            tempfile::{TempFile, TempFileConfig},
            MultipartForm,
        }
    };
    use actix_web::{middleware, web, App, Error, HttpResponse, HttpServer, Responder};
    use nanoid::nanoid;
    
    const BASE_DIR: &str = "/Users/mayankc/Work/source/perfComparisons/uploads/";
    
    #[derive(Debug, MultipartForm)]
    struct UploadForm {
        #[multipart(rename = "files")]
        files: Vec<TempFile>,
    }
    
    async fn save_files(
        MultipartForm(form): MultipartForm<UploadForm>,
    ) -> Result<impl Responder, Error> {
        for f in form.files {
            let path = format!("{}{}", BASE_DIR, nanoid!());
            f.file.persist(path).unwrap();
        }
    
        Ok(HttpResponse::Ok())
    }
    
    #[actix_web::main]
    async fn main() -> std::io::Result<()> {
        HttpServer::new(|| {
            App::new()
                .wrap(middleware::Logger::default())
                .app_data(TempFileConfig::default().directory(BASE_DIR))
                .service(
                    web::resource("/upload")
                        .route(web::post().to(save_files)),
                )
        })
        .bind(("127.0.0.1", 3000))?
        .run()
        .await
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    Rust代码已在release mode下编译。

    结果

    对10个、50个和100个并发连接执行测试。每个测试总共执行10万个请求。
    以下是结果:

    img

    img

    结论

    从结果中使用以下公式生成了一个评分表。对于每个测量,获取获胜的幅度。如果获胜幅度为:

    • < 5%,不给予任何分数
    • 在 5% 和 20% 之间,给予获胜者 1 分
    • 在 20% 和 50% 之间,给予获胜者 2 分
    • > 50%,给予获胜者 3 分

    img

    img

  • 相关阅读:
    Packet Tracer - 排除单区域 OSPFv2 故障
    【计算机网络】TCP协议
    OpenGL - Shadows
    远程办公会不会在未来五到十年成为普遍现象?
    关于Linux中作业调度 crond 和 systemd.timer 使用场景的一些笔记
    CSS3------盒模型
    Opencv——can‘t open/read file: check file path/integrity的解决办法
    JVM解析之类加载机制
    tomcat启动,测试被拒绝连接
    【C++刷题集】-- day3
  • 原文地址:https://blog.csdn.net/csjds/article/details/134483944