Skip to content

Instantly share code, notes, and snippets.

@idkravitz
Created February 14, 2020 04:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save idkravitz/8f8cde1aa29c4a81e3591d68b7ddc36c to your computer and use it in GitHub Desktop.
Save idkravitz/8f8cde1aa29c4a81e3591d68b7ddc36c to your computer and use it in GitHub Desktop.
String concatenations of non negative numbers in Rust.
[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"]
#![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