Skip to content

Reducing size of Color #31

@pickfire

Description

@pickfire

I want to give a try to reduce size of Color. Currently,

error: size: Size { raw: 216 }
  --> src/color/mod.rs:32:1
   |
32 | / pub(crate) struct Color {
33 | |     rgba: Rgba,
34 | |     hsla: Option<Hsla>,
35 | |     repr: String,
36 | | }
   | |_^

error: size: Size { raw: 96 }
  --> src/color/mod.rs:79:1
   |
79 | / struct Rgba {
80 | |     red: Number,
81 | |     green: Number,
82 | |     blue: Number,
83 | |     alpha: Number,
84 | | }
   | |_^

error: size: Size { raw: 32 }
  --> src/color/mod.rs:88:1
   |
88 | / struct Rgba2 {
89 | |     red: f64,
90 | |     green: f64,
91 | |     blue: f64,
92 | |     alpha: f64,
93 | | }
   | |_^

error: size: Size { raw: 24 }
  --> src/value/number/mod.rs:21:1
   |
21 | / pub(crate) enum Number {
22 | |     Small(Rational64),
23 | |     Big(Box<BigRational>),
24 | | }
   | |_^

Currently,

pub(crate) struct Color {
    rgba: Rgba,
    hsla: Option<Hsla>,
    repr: String,
}

struct Rgba {
    red: Number,
    green: Number,
    blue: Number,
    alpha: Number,
}

struct Hsla {
    hue: Number,
    saturation: Number,
    luminance: Number,
    alpha: Number,
}

It looks quite huge. I wonder if the following is possible.

pub(crate) struct Color {
    rgb: Rgb,
    // Do we really need an Option since usually I see either one of Rgba or Hsla can be specified?
    // Or can both be specified at the same time?
    // Or maybe just convert Hsla to Rgba and store only Rgba? Not sure if this works.
    hsl: Option<Hsl>,
    // I think we could probably follow libsass and use double precision here.
    alpha: f64,
    // I suggest using SmartString later on for this to allow small string optimization (23 bits could be stored in stack IIRC)
    // I wonder if it would be beneficial if this can be lazily calculated without keeping it in memory?
    repr: SmartString,
}

struct Rgb {
    // Since we are converting these to u8 later on, do we really need it to be Ratio or we can use u8?
    // Or is it used for those translate functions, I am not sure.
    // If u8 is not possible, I guess f64 would be a better choice.
    red: u8,
    green: u8,
    blue: u8,
}

// Have yet checked much on this yet, I bet u8 is not possible here.
struct Hsl {
    hue: f64,
    saturation: f64,
    luminance: f64,
}

This could probably get us to 64 bytes from 216. Or if we split out Hsla from a pointer (Box), we could probably get 32 bytes. I personally think it could be beneficial for cache lines to speed things up, not sure how true is this but we saw performance improvements last time for size reduction IIRC.

@connorskees What do you think?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions