Created
February 14, 2020 04:09
-
-
Save idkravitz/8f8cde1aa29c4a81e3591d68b7ddc36c to your computer and use it in GitHub Desktop.
String concatenations of non negative numbers in Rust.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "rustconcat" | |
version = "0.1.0" | |
authors = ["Dmitry Kravtsov <idkravitz@gmail.com>"] | |
edition = "2018" | |
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | |
[lib] | |
name="rustconcat" | |
crate-type=["cdylib"] | |
[profile.release] | |
incremental=false | |
codegen-units=1 | |
lto=true | |
[dependencies] | |
itoa="0.4.5" | |
[dependencies.pyo3] | |
version="0.9.0-alpha.1" | |
features=["extension-module"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(vec_into_raw_parts)] | |
use pyo3::prelude::*; | |
use pyo3::wrap_pyfunction; | |
use itoa; | |
use std::slice; | |
#[pyfunction] | |
fn rust_concat(n: usize) -> PyResult<String> { | |
let mut result = String::new(); | |
for i in 0..n { | |
result.push_str(&i.to_string()); | |
} | |
Ok(result) | |
} | |
#[pyfunction] | |
fn rust_concat2(n: usize) -> PyResult<String> { | |
let mut result = String::with_capacity(calculate_len(n)); | |
for i in 0..n { | |
result.push_str(&i.to_string()); | |
} | |
Ok(result) | |
} | |
fn calculate_len(n: usize) -> usize { | |
let mut l = 0; | |
let mut m = 1; | |
let mut b = 1; | |
while n > 10 * b { | |
l += m * b; | |
m += 1; | |
b *= 10; | |
} | |
9 * l + m * (n - b) + 1 | |
} | |
#[pyfunction] | |
fn concat_mutable(n: usize) -> PyResult<String> { | |
//#![feature(vec_into_raw_parts)] required to be in the beggining of file | |
// for following to work. Also may require rustc nightly profile in rustup | |
let (ptr, _, cap) = String::with_capacity(calculate_len(n)).into_raw_parts(); | |
let buff = unsafe { slice::from_raw_parts_mut(ptr, cap) }; | |
let mut offset = 0; | |
for i in 0..n { | |
let n_write = itoa::write(&mut buff[offset..], i)?; | |
offset += n_write; | |
} | |
Ok(unsafe { String::from_raw_parts(ptr, cap, cap) }) | |
} | |
#[pymodule] | |
fn rustconcat(_py: Python, m: &PyModule) -> PyResult<()> { | |
m.add_wrapped(wrap_pyfunction!(rust_concat))?; | |
m.add_wrapped(wrap_pyfunction!(rust_concat2))?; | |
m.add_wrapped(wrap_pyfunction!(concat_mutable))?; | |
Ok(()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment