Skip to content

Commit 85e2582

Browse files
Merge pull request #878 from sdroege/vec-conversion-optimizations
glib: Optimize various from/to `Vec` FFI translation functions
2 parents 08e6f30 + 4be06be commit 85e2582

File tree

7 files changed

+72
-69
lines changed

7 files changed

+72
-69
lines changed

glib/src/boxed.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,10 +231,12 @@ macro_rules! glib_boxed_wrapper {
231231
return Vec::new();
232232
}
233233

234-
let mut res = Vec::with_capacity(num);
234+
let mut res = Vec::<Self>::with_capacity(num);
235+
let res_ptr = res.as_mut_ptr();
235236
for i in 0..num {
236-
res.push($crate::translate::from_glib_none(std::ptr::read(ptr.add(i))));
237+
::std::ptr::write(res_ptr.add(i), $crate::translate::from_glib_none(std::ptr::read(ptr.add(i))));
237238
}
239+
res.set_len(num);
238240
res
239241
}
240242

@@ -251,9 +253,9 @@ macro_rules! glib_boxed_wrapper {
251253
}
252254

253255
let mut res = Vec::with_capacity(num);
254-
for i in 0..num {
255-
res.push($crate::translate::from_glib_full(std::ptr::read(ptr.add(i))));
256-
}
256+
let res_ptr = res.as_mut_ptr();
257+
::std::ptr::copy_nonoverlapping(ptr as *mut Self, res_ptr, num);
258+
res.set_len(num);
257259
$crate::ffi::g_free(ptr as *mut _);
258260
res
259261
}

glib/src/boxed_inline.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -439,10 +439,12 @@ macro_rules! glib_boxed_inline_wrapper {
439439
return Vec::new();
440440
}
441441

442-
let mut res = Vec::with_capacity(num);
442+
let mut res = Vec::<Self>::with_capacity(num);
443+
let res_ptr = res.as_mut_ptr();
443444
for i in 0..num {
444-
res.push($crate::translate::from_glib_none(ptr.add(i)));
445+
::std::ptr::write(res_ptr.add(i), $crate::translate::from_glib_none(ptr.add(i)));
445446
}
447+
res.set_len(num);
446448
res
447449
}
448450

@@ -459,9 +461,9 @@ macro_rules! glib_boxed_inline_wrapper {
459461
}
460462

461463
let mut res = Vec::with_capacity(num);
462-
for i in 0..num {
463-
res.push(std::ptr::read(ptr.add(i) as *const $name $(<$($generic),+>)?));
464-
}
464+
let res_ptr = res.as_mut_ptr();
465+
::std::ptr::copy_nonoverlapping(ptr as *mut Self, res_ptr, num);
466+
res.set_len(num);
465467
$crate::ffi::g_free(ptr as *mut _);
466468
res
467469
}
@@ -474,10 +476,12 @@ macro_rules! glib_boxed_inline_wrapper {
474476
return Vec::new();
475477
}
476478

477-
let mut res = Vec::with_capacity(num);
479+
let mut res = Vec::<Self>::with_capacity(num);
480+
let res_ptr = res.as_mut_ptr();
478481
for i in 0..num {
479-
res.push($crate::translate::from_glib_none(std::ptr::read(ptr.add(i))));
482+
::std::ptr::write(res_ptr.add(i), $crate::translate::from_glib_none(::std::ptr::read(ptr.add(i))));
480483
}
484+
res.set_len(num);
481485
res
482486
}
483487

@@ -493,10 +497,12 @@ macro_rules! glib_boxed_inline_wrapper {
493497
return Vec::new();
494498
}
495499

496-
let mut res = Vec::with_capacity(num);
500+
let mut res = Vec::<Self>::with_capacity(num);
501+
let res_ptr = res.as_mut_ptr();
497502
for i in 0..num {
498-
res.push($crate::translate::from_glib_full(std::ptr::read(ptr.add(i))));
503+
::std::ptr::write(res_ptr.add(i), $crate::translate::from_glib_full(::std::ptr::read(ptr.add(i))));
499504
}
505+
res.set_len(num);
500506
$crate::ffi::g_free(ptr as *mut _);
501507
res
502508
}

glib/src/object.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -943,10 +943,12 @@ macro_rules! glib_object_wrapper {
943943
return Vec::new();
944944
}
945945

946-
let mut res = Vec::with_capacity(num);
946+
let mut res = Vec::<Self>::with_capacity(num);
947+
let res_ptr = res.as_mut_ptr();
947948
for i in 0..num {
948-
res.push($crate::translate::from_glib_none(std::ptr::read(ptr.add(i))));
949+
::std::ptr::write(res_ptr.add(i), $crate::translate::from_glib_none(std::ptr::read(ptr.add(i))));
949950
}
951+
res.set_len(num);
950952
res
951953
}
952954

@@ -963,9 +965,9 @@ macro_rules! glib_object_wrapper {
963965
}
964966

965967
let mut res = Vec::with_capacity(num);
966-
for i in 0..num {
967-
res.push($crate::translate::from_glib_full(std::ptr::read(ptr.add(i))));
968-
}
968+
let res_ptr = res.as_mut_ptr();
969+
::std::ptr::copy_nonoverlapping(ptr as *mut Self, res_ptr, num);
970+
res.set_len(num);
969971
$crate::ffi::g_free(ptr as *mut _);
970972
res
971973
}

glib/src/shared.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,12 @@ macro_rules! glib_shared_wrapper {
232232
return Vec::new();
233233
}
234234

235-
let mut res = Vec::with_capacity(num);
235+
let mut res = Vec::<Self>::with_capacity(num);
236+
let res_ptr = res.as_mut_ptr();
236237
for i in 0..num {
237-
res.push($crate::translate::from_glib_none(std::ptr::read(ptr.add(i))));
238+
::std::ptr::write(res_ptr.add(i), $crate::translate::from_glib_none(std::ptr::read(ptr.add(i))));
238239
}
240+
res.set_len(num);
239241
res
240242
}
241243

@@ -252,9 +254,9 @@ macro_rules! glib_shared_wrapper {
252254
}
253255

254256
let mut res = Vec::with_capacity(num);
255-
for i in 0..num {
256-
res.push($crate::translate::from_glib_full(std::ptr::read(ptr.add(i))));
257-
}
257+
let res_ptr = res.as_mut_ptr();
258+
::std::ptr::copy_nonoverlapping(ptr as *mut Self, res_ptr, num);
259+
res.set_len(num);
258260
$crate::ffi::g_free(ptr as *mut _);
259261
res
260262
}

glib/src/subclass/signal.rs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -354,30 +354,6 @@ impl IntoGlib for SignalType {
354354
}
355355
}
356356

357-
impl FromGlibContainerAsVec<Type, *const ffi::GType> for SignalType {
358-
unsafe fn from_glib_none_num_as_vec(ptr: *const ffi::GType, num: usize) -> Vec<Self> {
359-
if num == 0 || ptr.is_null() {
360-
return Vec::new();
361-
}
362-
363-
let mut res = Vec::with_capacity(num);
364-
for i in 0..num {
365-
res.push(from_glib(*ptr.add(i)));
366-
}
367-
res
368-
}
369-
370-
unsafe fn from_glib_container_num_as_vec(_: *const ffi::GType, _: usize) -> Vec<Self> {
371-
// Can't really free a *const
372-
unimplemented!();
373-
}
374-
375-
unsafe fn from_glib_full_num_as_vec(_: *const ffi::GType, _: usize) -> Vec<Self> {
376-
// Can't really free a *const
377-
unimplemented!();
378-
}
379-
}
380-
381357
#[allow(clippy::type_complexity)]
382358
enum SignalRegistration {
383359
Unregistered {

glib/src/translate.rs

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -995,12 +995,13 @@ macro_rules! impl_to_glib_container_from_slice_string {
995995
let v: Vec<_> = t.iter().map(ToGlibPtr::to_glib_none).collect();
996996

997997
let v_ptr = unsafe {
998-
let v_ptr = ffi::g_malloc0(mem::size_of::<$ffi_name>() * (t.len() + 1))
998+
let v_ptr = ffi::g_malloc(mem::size_of::<$ffi_name>() * (t.len() + 1))
999999
as *mut $ffi_name;
10001000

10011001
for (i, s) in v.iter().enumerate() {
10021002
ptr::write(v_ptr.add(i), s.0);
10031003
}
1004+
ptr::write(v_ptr.add(t.len()), ptr::null_mut());
10041005

10051006
v_ptr
10061007
};
@@ -1010,12 +1011,13 @@ macro_rules! impl_to_glib_container_from_slice_string {
10101011

10111012
fn to_glib_full_from_slice(t: &[$name]) -> *mut $ffi_name {
10121013
unsafe {
1013-
let v_ptr = ffi::g_malloc0(mem::size_of::<$ffi_name>() * (t.len() + 1))
1014+
let v_ptr = ffi::g_malloc(mem::size_of::<$ffi_name>() * (t.len() + 1))
10141015
as *mut $ffi_name;
10151016

10161017
for (i, s) in t.iter().enumerate() {
10171018
ptr::write(v_ptr.add(i), s.to_glib_full());
10181019
}
1020+
ptr::write(v_ptr.add(t.len()), ptr::null_mut());
10191021

10201022
v_ptr
10211023
}
@@ -1036,12 +1038,13 @@ macro_rules! impl_to_glib_container_from_slice_string {
10361038
let v: Vec<_> = t.iter().map(ToGlibPtr::to_glib_none).collect();
10371039

10381040
let v_ptr = unsafe {
1039-
let v_ptr = ffi::g_malloc0(mem::size_of::<$ffi_name>() * (t.len() + 1))
1041+
let v_ptr = ffi::g_malloc(mem::size_of::<$ffi_name>() * (t.len() + 1))
10401042
as *mut $ffi_name;
10411043

10421044
for (i, s) in v.iter().enumerate() {
10431045
ptr::write(v_ptr.add(i), s.0);
10441046
}
1047+
ptr::write(v_ptr.add(t.len()), ptr::null_mut());
10451048

10461049
v_ptr as *const $ffi_name
10471050
};
@@ -1051,12 +1054,13 @@ macro_rules! impl_to_glib_container_from_slice_string {
10511054

10521055
fn to_glib_full_from_slice(t: &[$name]) -> *const $ffi_name {
10531056
unsafe {
1054-
let v_ptr = ffi::g_malloc0(mem::size_of::<$ffi_name>() * (t.len() + 1))
1057+
let v_ptr = ffi::g_malloc(mem::size_of::<$ffi_name>() * (t.len() + 1))
10551058
as *mut $ffi_name;
10561059

10571060
for (i, s) in t.iter().enumerate() {
10581061
ptr::write(v_ptr.add(i), s.to_glib_full());
10591062
}
1063+
ptr::write(v_ptr.add(t.len()), ptr::null_mut());
10601064

10611065
v_ptr as *const $ffi_name
10621066
}
@@ -1966,10 +1970,12 @@ impl FromGlibContainerAsVec<bool, *const ffi::gboolean> for bool {
19661970
return Vec::new();
19671971
}
19681972

1969-
let mut res = Vec::with_capacity(num);
1973+
let mut res = Vec::<Self>::with_capacity(num);
1974+
let res_ptr = res.as_mut_ptr();
19701975
for i in 0..num {
1971-
res.push(from_glib(ptr::read(ptr.add(i))));
1976+
*res_ptr.add(i) = from_glib(ptr::read(ptr.add(i)));
19721977
}
1978+
res.set_len(num);
19731979
res
19741980
}
19751981

@@ -2013,9 +2019,9 @@ macro_rules! impl_from_glib_container_as_vec_fundamental {
20132019
}
20142020

20152021
let mut res = Vec::with_capacity(num);
2016-
for i in 0..num {
2017-
res.push(ptr::read(ptr.add(i)));
2018-
}
2022+
let res_ptr = res.as_mut_ptr();
2023+
std::ptr::copy_nonoverlapping(ptr, res_ptr, num);
2024+
res.set_len(num);
20192025
res
20202026
}
20212027

@@ -2067,10 +2073,15 @@ macro_rules! impl_from_glib_container_as_vec_string {
20672073
return Vec::new();
20682074
}
20692075

2070-
let mut res = Vec::with_capacity(num);
2076+
let mut res = Vec::<Self>::with_capacity(num);
2077+
let res_ptr = res.as_mut_ptr();
20712078
for i in 0..num {
2072-
res.push(from_glib_none(ptr::read(ptr.add(i)) as $ffi_name));
2079+
std::ptr::write(
2080+
res_ptr.add(i),
2081+
from_glib_none(ptr::read(ptr.add(i)) as $ffi_name),
2082+
);
20732083
}
2084+
res.set_len(num);
20742085
res
20752086
}
20762087

@@ -2102,10 +2113,15 @@ macro_rules! impl_from_glib_container_as_vec_string {
21022113
return Vec::new();
21032114
}
21042115

2105-
let mut res = Vec::with_capacity(num);
2116+
let mut res = Vec::<Self>::with_capacity(num);
2117+
let res_ptr = res.as_mut_ptr();
21062118
for i in 0..num {
2107-
res.push(from_glib_full(ptr::read(ptr.add(i))));
2119+
std::ptr::write(
2120+
res_ptr.add(i),
2121+
from_glib_full(ptr::read(ptr.add(i)) as $ffi_name),
2122+
);
21082123
}
2124+
res.set_len(num);
21092125
ffi::g_free(ptr as *mut _);
21102126
res
21112127
}

glib/src/types.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -560,10 +560,9 @@ impl<'a> ToGlibContainerFromSlice<'a, *mut ffi::GType> for Type {
560560

561561
unsafe {
562562
let res =
563-
ffi::g_malloc0(mem::size_of::<ffi::GType>() * (t.len() + 1)) as *mut ffi::GType;
564-
for (i, v) in t.iter().enumerate() {
565-
*res.add(i) = v.into_glib();
566-
}
563+
ffi::g_malloc(mem::size_of::<ffi::GType>() * (t.len() + 1)) as *mut ffi::GType;
564+
std::ptr::copy_nonoverlapping(t.as_ptr() as *const ffi::GType, res, t.len());
565+
*res.add(t.len()) = 0;
567566
res
568567
}
569568
}
@@ -575,10 +574,10 @@ impl FromGlibContainerAsVec<Type, *const ffi::GType> for Type {
575574
return Vec::new();
576575
}
577576

578-
let mut res = Vec::with_capacity(num);
579-
for i in 0..num {
580-
res.push(from_glib(*ptr.add(i)));
581-
}
577+
let mut res = Vec::<Self>::with_capacity(num);
578+
let res_ptr = res.as_mut_ptr() as *mut ffi::GType;
579+
std::ptr::copy_nonoverlapping(ptr, res_ptr, num);
580+
res.set_len(num);
582581
res
583582
}
584583

0 commit comments

Comments
 (0)