Picking up where we left off, the vanilla Vector and Rw_Vector apis support very flexible vector functionality, but this flexibility comes at a price.
In order to be able to hold values of any type, a vector is implemented as a vector of pointers to the actual values. This way the vector elements can be anything from 8-bit unsigned values to 64-bit floats to perhaps entire binary trees, images, symbol tables or relational database tables.
Consequently, every vector vector or rw_vector element stored has the space overhead of the in-vector pointer plus any per-element space overhead due to the memory allocation subsystem implementation and memory alignment restrictions. In the case of a vector holding 64-bit floats, this may easily triple the amount of memory required; in the case of a vector holding 8-bit unsigned values this may result in memory consumption an order of magnitude higher than optimum.
Constantly indirecting through these vector pointers also increases the CPU time overhead required for vector computations.
Most of the time these space and time overhead costs are of negligible practical importance, a more than justifiable price to pay for code simplicity and cleanliness.
But sometimes these costs are significant enough that is worth some increase in code complexity in order to reduce them.
For such times Mythryl provides a variety of typelocked vector implementations where by “typelocked” we mean specialized to a particular type of element. The Typelocked_Vector and Typelocked_Rw_Vector apis define the interfaces for these implementations, which include vector_of_chars,vector_of_one_byte_unts,vector_of_eight_byte_floats,rw_vector_of_chars,rw_vector_of_one_byte_unts and rw_vector_of_eight_byte_floats packages.
The typelocked vector apis are very similar to the vanilla vector apis; often you will simply be able to substitute the appropriate typelocked vector package for the vanilla one and soldier on with increased space and time efficiency:
linux$ my eval: v = vector_of_one_byte_unts::from_list (map one_byte_unt::from_int [ 1, 2, 3, 4 ]); eval: vector_of_one_byte_unts::get (v, 0); 0wx1 eval: vector_of_one_byte_unts::get (v, 1); 0wx2 eval: vector_of_one_byte_unts::get (v, 2); 0wx3 eval: v = rw_vector_of_one_byte_unts::make_rw_vector( 4, 0wx0 ); eval: for (i = 0; i < 4; ++i) printf "%d\n" (one_byte_unt::to_int (rw_vector_of_one_byte_unts::get(v,i))); 0 0 0 0 eval: rw_vector_of_one_byte_unts::set( v, 0, 0wx12 ); eval: rw_vector_of_one_byte_unts::set( v, 1, 0wx45 ); eval: for (i = 0; i < 4; ++i) printf "%d\n" (one_byte_unt::to_int (rw_vector_of_one_byte_unts::get(v,i))); 18 69 0 0 eval: package fv = rw_vector_of_eight_byte_floats; eval: v = fv::make_rw_vector( 4, 0.0 ); eval: for (i = 0; i < 4; ++i) printf "%f\n" (rw_vector_of_eight_byte_floats::get(v,i)); 0.000000 0.000000 0.000000 0.000000 eval: fv::set( v, 0, 3.141592 ); eval: fv::set( v, 1, 2.718281 ); eval: for (i = 0; i < 4; ++i) printf "%f\n" (rw_vector_of_eight_byte_floats::get(v,i)); 3.141592 2.718282 0.000000 0.000000