perf: accelerate kitty graphics protocol encoding by avoiding string reallocation (#837)

This commit is contained in:
三咲雅 · Misaki Masa 2024-03-23 13:34:46 +08:00 committed by GitHub
parent 9ba47141bf
commit f8e0aee311
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 8 additions and 6 deletions

View file

@ -1,3 +1,4 @@
use core::str;
use std::{io::{stderr, BufWriter, Write}, path::Path}; use std::{io::{stderr, BufWriter, Write}, path::Path};
use anyhow::Result; use anyhow::Result;
@ -344,7 +345,7 @@ impl Kitty {
async fn encode(img: DynamicImage) -> Result<Vec<u8>> { async fn encode(img: DynamicImage) -> Result<Vec<u8>> {
fn output(raw: &[u8], format: u8, size: (u32, u32)) -> Result<Vec<u8>> { fn output(raw: &[u8], format: u8, size: (u32, u32)) -> Result<Vec<u8>> {
let b64: Vec<_> = general_purpose::STANDARD.encode(raw).chars().collect(); let b64 = general_purpose::STANDARD.encode(raw).into_bytes();
let mut it = b64.chunks(4096).peekable(); let mut it = b64.chunks(4096).peekable();
let mut buf = Vec::with_capacity(b64.len() + it.len() * 50); let mut buf = Vec::with_capacity(b64.len() + it.len() * 50);
@ -357,7 +358,7 @@ impl Kitty {
size.0, size.0,
size.1, size.1,
it.peek().is_some() as u8, it.peek().is_some() as u8,
first.iter().collect::<String>(), unsafe { str::from_utf8_unchecked(first) },
ESCAPE, ESCAPE,
CLOSE CLOSE
)?; )?;
@ -369,7 +370,7 @@ impl Kitty {
"{}_Gm={};{}{}\\{}", "{}_Gm={};{}{}\\{}",
START, START,
it.peek().is_some() as u8, it.peek().is_some() as u8,
chunk.iter().collect::<String>(), unsafe { str::from_utf8_unchecked(chunk) },
ESCAPE, ESCAPE,
CLOSE CLOSE
)?; )?;

View file

@ -1,3 +1,4 @@
use core::str;
use std::{io::{stderr, Write}, path::Path}; use std::{io::{stderr, Write}, path::Path};
use anyhow::Result; use anyhow::Result;
@ -35,7 +36,7 @@ impl KittyOld {
async fn encode(img: DynamicImage) -> Result<Vec<u8>> { async fn encode(img: DynamicImage) -> Result<Vec<u8>> {
fn output(raw: &[u8], format: u8, size: (u32, u32)) -> Result<Vec<u8>> { fn output(raw: &[u8], format: u8, size: (u32, u32)) -> Result<Vec<u8>> {
let b64: Vec<_> = general_purpose::STANDARD.encode(raw).chars().collect(); let b64 = general_purpose::STANDARD.encode(raw).into_bytes();
let mut it = b64.chunks(4096).peekable(); let mut it = b64.chunks(4096).peekable();
let mut buf = Vec::with_capacity(b64.len() + it.len() * 50); let mut buf = Vec::with_capacity(b64.len() + it.len() * 50);
@ -48,7 +49,7 @@ impl KittyOld {
size.0, size.0,
size.1, size.1,
it.peek().is_some() as u8, it.peek().is_some() as u8,
first.iter().collect::<String>(), unsafe { str::from_utf8_unchecked(first) },
ESCAPE, ESCAPE,
CLOSE CLOSE
)?; )?;
@ -60,7 +61,7 @@ impl KittyOld {
"{}_Gm={};{}{}\\{}", "{}_Gm={};{}{}\\{}",
START, START,
it.peek().is_some() as u8, it.peek().is_some() as u8,
chunk.iter().collect::<String>(), unsafe { str::from_utf8_unchecked(chunk) },
ESCAPE, ESCAPE,
CLOSE CLOSE
)?; )?;