Parallel Letter Frequency
This commit is contained in:
parent
3ca9867a11
commit
af89290bbc
45 changed files with 2862 additions and 0 deletions
42
rust/parallel-letter-frequency/.exercism/config.json
Normal file
42
rust/parallel-letter-frequency/.exercism/config.json
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"authors": [
|
||||
"EduardoBautista"
|
||||
],
|
||||
"contributors": [
|
||||
"andrewclarkson",
|
||||
"ashleygwilliams",
|
||||
"ccouzens",
|
||||
"ClashTheBunny",
|
||||
"coriolinus",
|
||||
"cwhakes",
|
||||
"EduardoBautista",
|
||||
"efx",
|
||||
"ErikSchierboom",
|
||||
"etrepum",
|
||||
"glennpratt",
|
||||
"IanWhitney",
|
||||
"kytrinyx",
|
||||
"lutostag",
|
||||
"mkantor",
|
||||
"nfiles",
|
||||
"petertseng",
|
||||
"rofrol",
|
||||
"sjwarner-bp",
|
||||
"stringparser",
|
||||
"xakon",
|
||||
"ZapAnton"
|
||||
],
|
||||
"files": {
|
||||
"solution": [
|
||||
"src/lib.rs",
|
||||
"Cargo.toml"
|
||||
],
|
||||
"test": [
|
||||
"tests/parallel_letter_frequency.rs"
|
||||
],
|
||||
"example": [
|
||||
".meta/example.rs"
|
||||
]
|
||||
},
|
||||
"blurb": "Count the frequency of letters in texts using parallel computation."
|
||||
}
|
||||
2
rust/parallel-letter-frequency/.gitignore
vendored
Normal file
2
rust/parallel-letter-frequency/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
Cargo.lock
|
||||
9
rust/parallel-letter-frequency/Cargo.toml
Normal file
9
rust/parallel-letter-frequency/Cargo.toml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "parallel_letter_frequency"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
# Not all libraries from crates.io are available in Exercism's test runner.
|
||||
# The full list of available libraries is here:
|
||||
# https://github.com/exercism/rust-test-runner/blob/main/local-registry/Cargo.toml
|
||||
[dependencies]
|
||||
89
rust/parallel-letter-frequency/HELP.md
Normal file
89
rust/parallel-letter-frequency/HELP.md
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# Help
|
||||
|
||||
## Running the tests
|
||||
|
||||
Execute the tests with:
|
||||
|
||||
```bash
|
||||
$ cargo test
|
||||
```
|
||||
|
||||
All but the first test have been ignored. After you get the first test to
|
||||
pass, open the tests source file which is located in the `tests` directory
|
||||
and remove the `#[ignore]` flag from the next test and get the tests to pass
|
||||
again. Each separate test is a function with `#[test]` flag above it.
|
||||
Continue, until you pass every test.
|
||||
|
||||
If you wish to run _only ignored_ tests without editing the tests source file, use:
|
||||
|
||||
```bash
|
||||
$ cargo test -- --ignored
|
||||
```
|
||||
|
||||
If you are using Rust 1.51 or later, you can run _all_ tests with
|
||||
|
||||
```bash
|
||||
$ cargo test -- --include-ignored
|
||||
```
|
||||
|
||||
To run a specific test, for example `some_test`, you can use:
|
||||
|
||||
```bash
|
||||
$ cargo test some_test
|
||||
```
|
||||
|
||||
If the specific test is ignored, use:
|
||||
|
||||
```bash
|
||||
$ cargo test some_test -- --ignored
|
||||
```
|
||||
|
||||
To learn more about Rust tests refer to the online [test documentation][rust-tests].
|
||||
|
||||
[rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html
|
||||
|
||||
## Submitting your solution
|
||||
|
||||
You can submit your solution using the `exercism submit src/lib.rs Cargo.toml` command.
|
||||
This command will upload your solution to the Exercism website and print the solution page's URL.
|
||||
|
||||
It's possible to submit an incomplete solution which allows you to:
|
||||
|
||||
- See how others have completed the exercise
|
||||
- Request help from a mentor
|
||||
|
||||
## Need to get help?
|
||||
|
||||
If you'd like help solving the exercise, check the following pages:
|
||||
|
||||
- The [Rust track's documentation](https://exercism.org/docs/tracks/rust)
|
||||
- The [Rust track's programming category on the forum](https://forum.exercism.org/c/programming/rust)
|
||||
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
|
||||
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
|
||||
|
||||
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
|
||||
|
||||
## Rust Installation
|
||||
|
||||
Refer to the [exercism help page][help-page] for Rust installation and learning
|
||||
resources.
|
||||
|
||||
## Submitting the solution
|
||||
|
||||
Generally you should submit all files in which you implemented your solution (`src/lib.rs` in most cases). If you are using any external crates, please consider submitting the `Cargo.toml` file. This will make the review process faster and clearer.
|
||||
|
||||
## Feedback, Issues, Pull Requests
|
||||
|
||||
Head to [the forum](https://forum.exercism.org/c/programming/rust/) and create a post to provide feedback about an exercise or if you want to help implement new exercises.
|
||||
Members of the rust track team are happy to help!
|
||||
|
||||
The GitHub [track repository][github] is the home for all of the Rust exercises.
|
||||
|
||||
If you want to know more about Exercism, take a look at the [contribution guide].
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
||||
|
||||
[help-page]: https://exercism.org/tracks/rust/learning
|
||||
[github]: https://github.com/exercism/rust
|
||||
[contribution guide]: https://exercism.org/docs/community/contributors
|
||||
76
rust/parallel-letter-frequency/README.md
Normal file
76
rust/parallel-letter-frequency/README.md
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
# Parallel Letter Frequency
|
||||
|
||||
Welcome to Parallel Letter Frequency on Exercism's Rust Track.
|
||||
If you need help running the tests or submitting your code, check out `HELP.md`.
|
||||
|
||||
## Instructions
|
||||
|
||||
Count the frequency of letters in texts using parallel computation.
|
||||
|
||||
Parallelism is about doing things in parallel that can also be done sequentially.
|
||||
A common example is counting the frequency of letters.
|
||||
Employ parallelism to calculate the total frequency of each letter in a list of texts.
|
||||
|
||||
## Parallel Letter Frequency in Rust
|
||||
|
||||
Learn more about concurrency in Rust here:
|
||||
|
||||
- [Concurrency](https://doc.rust-lang.org/book/ch16-00-concurrency.html)
|
||||
|
||||
## Bonus
|
||||
|
||||
This exercise also includes a benchmark, with a sequential implementation as a
|
||||
baseline. You can compare your solution to the benchmark. Observe the
|
||||
effect different size inputs have on the performance of each. Can you
|
||||
surpass the benchmark using concurrent programming techniques?
|
||||
|
||||
As of this writing, test::Bencher is unstable and only available on
|
||||
*nightly* Rust. Run the benchmarks with Cargo:
|
||||
|
||||
```
|
||||
cargo bench
|
||||
```
|
||||
|
||||
If you are using rustup.rs:
|
||||
|
||||
```
|
||||
rustup run nightly cargo bench
|
||||
```
|
||||
|
||||
- [Benchmark tests](https://doc.rust-lang.org/stable/unstable-book/library-features/test.html)
|
||||
|
||||
Learn more about nightly Rust:
|
||||
|
||||
- [Nightly Rust](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html)
|
||||
- [Installing Rust nightly](https://rust-lang.github.io/rustup/concepts/channels.html#working-with-nightly-rust)
|
||||
|
||||
## Source
|
||||
|
||||
### Created by
|
||||
|
||||
- @EduardoBautista
|
||||
|
||||
### Contributed to by
|
||||
|
||||
- @andrewclarkson
|
||||
- @ashleygwilliams
|
||||
- @ccouzens
|
||||
- @ClashTheBunny
|
||||
- @coriolinus
|
||||
- @cwhakes
|
||||
- @EduardoBautista
|
||||
- @efx
|
||||
- @ErikSchierboom
|
||||
- @etrepum
|
||||
- @glennpratt
|
||||
- @IanWhitney
|
||||
- @kytrinyx
|
||||
- @lutostag
|
||||
- @mkantor
|
||||
- @nfiles
|
||||
- @petertseng
|
||||
- @rofrol
|
||||
- @sjwarner-bp
|
||||
- @stringparser
|
||||
- @xakon
|
||||
- @ZapAnton
|
||||
102
rust/parallel-letter-frequency/benches/benchmark.rs
Normal file
102
rust/parallel-letter-frequency/benches/benchmark.rs
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
#![feature(test)]
|
||||
extern crate parallel_letter_frequency;
|
||||
extern crate test;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use test::Bencher;
|
||||
|
||||
#[bench]
|
||||
fn bench_tiny_parallel(b: &mut Bencher) {
|
||||
let tiny = &["a"];
|
||||
b.iter(|| parallel_letter_frequency::frequency(tiny, 3));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_tiny_sequential(b: &mut Bencher) {
|
||||
let tiny = &["a"];
|
||||
b.iter(|| frequency(tiny));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_small_parallel(b: &mut Bencher) {
|
||||
let texts = all_texts(1);
|
||||
b.iter(|| parallel_letter_frequency::frequency(&texts, 3));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_small_sequential(b: &mut Bencher) {
|
||||
let texts = all_texts(1);
|
||||
b.iter(|| frequency(&texts));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_large_parallel(b: &mut Bencher) {
|
||||
let texts = all_texts(30);
|
||||
b.iter(|| parallel_letter_frequency::frequency(&texts, 3));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_large_sequential(b: &mut Bencher) {
|
||||
let texts = all_texts(30);
|
||||
b.iter(|| frequency(&texts));
|
||||
}
|
||||
|
||||
/// Simple sequential char frequency. Can it be beat?
|
||||
pub fn frequency(texts: &[&str]) -> HashMap<char, usize> {
|
||||
let mut map = HashMap::new();
|
||||
|
||||
for line in texts {
|
||||
for chr in line.chars().filter(|c| c.is_alphabetic()) {
|
||||
if let Some(c) = chr.to_lowercase().next() {
|
||||
(*map.entry(c).or_insert(0)) += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map
|
||||
}
|
||||
|
||||
fn all_texts(repeat: usize) -> Vec<&'static str> {
|
||||
[ODE_AN_DIE_FREUDE, WILHELMUS, STAR_SPANGLED_BANNER]
|
||||
.iter()
|
||||
.cycle()
|
||||
.take(3 * repeat)
|
||||
.flat_map(|anthem| anthem.iter().cloned())
|
||||
.collect()
|
||||
}
|
||||
|
||||
// Poem by Friedrich Schiller. The corresponding music is the European Anthem.
|
||||
pub const ODE_AN_DIE_FREUDE: [&str; 8] = [
|
||||
"Freude schöner Götterfunken",
|
||||
"Tochter aus Elysium,",
|
||||
"Wir betreten feuertrunken,",
|
||||
"Himmlische, dein Heiligtum!",
|
||||
"Deine Zauber binden wieder",
|
||||
"Was die Mode streng geteilt;",
|
||||
"Alle Menschen werden Brüder,",
|
||||
"Wo dein sanfter Flügel weilt.",
|
||||
];
|
||||
|
||||
// Dutch national anthem
|
||||
pub const WILHELMUS: [&str; 8] = [
|
||||
"Wilhelmus van Nassouwe",
|
||||
"ben ik, van Duitsen bloed,",
|
||||
"den vaderland getrouwe",
|
||||
"blijf ik tot in den dood.",
|
||||
"Een Prinse van Oranje",
|
||||
"ben ik, vrij, onverveerd,",
|
||||
"den Koning van Hispanje",
|
||||
"heb ik altijd geëerd.",
|
||||
];
|
||||
|
||||
// American national anthem
|
||||
pub const STAR_SPANGLED_BANNER: [&str; 8] = [
|
||||
"O say can you see by the dawn's early light,",
|
||||
"What so proudly we hailed at the twilight's last gleaming,",
|
||||
"Whose broad stripes and bright stars through the perilous fight,",
|
||||
"O'er the ramparts we watched, were so gallantly streaming?",
|
||||
"And the rockets' red glare, the bombs bursting in air,",
|
||||
"Gave proof through the night that our flag was still there;",
|
||||
"O say does that star-spangled banner yet wave,",
|
||||
"O'er the land of the free and the home of the brave?",
|
||||
];
|
||||
41
rust/parallel-letter-frequency/src/lib.rs
Normal file
41
rust/parallel-letter-frequency/src/lib.rs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use std::thread;
|
||||
|
||||
pub fn frequency(input: &[&str], worker_count: usize) -> HashMap<char, usize> {
|
||||
if input.is_empty() {
|
||||
return HashMap::<char, usize>::new();
|
||||
}
|
||||
|
||||
let worker_count = worker_count.max(1);
|
||||
|
||||
thread::scope(|s| {
|
||||
let chunk_size = input.len().div_ceil(worker_count);
|
||||
let mut handles: Vec<_> = input
|
||||
.chunks(chunk_size)
|
||||
.map(|chunk| {
|
||||
s.spawn(move || {
|
||||
let mut proxy_map = HashMap::new();
|
||||
chunk
|
||||
.iter()
|
||||
.flat_map(|line| line.chars())
|
||||
.filter(|char| char.is_alphabetic())
|
||||
.flat_map(|char_slice| char_slice.to_lowercase())
|
||||
.for_each(|char| {
|
||||
*proxy_map.entry(char).or_insert(0) += 1;
|
||||
});
|
||||
proxy_map
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
handles
|
||||
.into_iter()
|
||||
.map(|x| x.join().unwrap())
|
||||
.fold(HashMap::new(), |mut acc, map| {
|
||||
for (char, count) in map {
|
||||
*acc.entry(char).or_insert(0) += count;
|
||||
}
|
||||
acc
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,347 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use parallel_letter_frequency as frequency;
|
||||
|
||||
#[test]
|
||||
fn no_texts() {
|
||||
assert_eq!(frequency::frequency(&[], 4), HashMap::new());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn one_text_with_one_letter() {
|
||||
let mut hm = HashMap::new();
|
||||
hm.insert('a', 1);
|
||||
assert_eq!(frequency::frequency(&["a"], 4), hm);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn one_text_with_multiple_letters() {
|
||||
let mut hm = HashMap::new();
|
||||
hm.insert('b', 2);
|
||||
hm.insert('c', 3);
|
||||
hm.insert('d', 1);
|
||||
assert_eq!(frequency::frequency(&["bbcccd"], 4), hm);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn two_texts_with_one_letter() {
|
||||
let mut hm = HashMap::new();
|
||||
hm.insert('e', 1);
|
||||
hm.insert('f', 1);
|
||||
assert_eq!(frequency::frequency(&["e", "f"], 4), hm);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn two_texts_with_multiple_letters() {
|
||||
let mut hm = HashMap::new();
|
||||
hm.insert('g', 2);
|
||||
hm.insert('h', 3);
|
||||
hm.insert('i', 1);
|
||||
assert_eq!(frequency::frequency(&["ggh", "hhi"], 4), hm);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn case_insensitivity() {
|
||||
let mut hm = HashMap::new();
|
||||
hm.insert('a', 2);
|
||||
assert_eq!(frequency::frequency(&["aA"], 4), hm);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn many_empty_lines() {
|
||||
let v = vec![""; 1000];
|
||||
assert_eq!(frequency::frequency(&v[..], 4), HashMap::new());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignore_whitespace() {
|
||||
let v = [" ", "\t", "\r\n"];
|
||||
assert_eq!(frequency::frequency(&v[..], 4), HashMap::new());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn many_times_same_text() {
|
||||
let v = vec!["abc"; 1000];
|
||||
let mut hm = HashMap::new();
|
||||
hm.insert('a', 1000);
|
||||
hm.insert('b', 1000);
|
||||
hm.insert('c', 1000);
|
||||
assert_eq!(frequency::frequency(&v[..], 4), hm);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn punctuation_doesnt_count() {
|
||||
assert!(!frequency::frequency(&WILHELMUS, 4).contains_key(&','));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn numbers_dont_count() {
|
||||
assert!(!frequency::frequency(&["Testing, 1, 2, 3"], 4).contains_key(&'1'));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unicode_letters() {
|
||||
let mut hm = HashMap::new();
|
||||
hm.insert('本', 1);
|
||||
hm.insert('φ', 1);
|
||||
hm.insert('ほ', 1);
|
||||
hm.insert('ø', 1);
|
||||
let v = ["本", "φ", "ほ", "ø"];
|
||||
assert_eq!(frequency::frequency(&v, 4), hm);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_three_anthems_1_worker() {
|
||||
let mut v = Vec::new();
|
||||
// These constants can be found under the last test if you wish to see them
|
||||
for anthem in [ODE_AN_DIE_FREUDE, WILHELMUS, STAR_SPANGLED_BANNER].iter() {
|
||||
for line in anthem.iter() {
|
||||
v.push(*line);
|
||||
}
|
||||
}
|
||||
let freqs = frequency::frequency(&v[..], 1);
|
||||
assert_eq!(freqs.get(&'a'), Some(&49));
|
||||
assert_eq!(freqs.get(&'t'), Some(&56));
|
||||
assert_eq!(freqs.get(&'ü'), Some(&2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_three_anthems_3_workers() {
|
||||
let mut v = Vec::new();
|
||||
for anthem in [ODE_AN_DIE_FREUDE, WILHELMUS, STAR_SPANGLED_BANNER].iter() {
|
||||
for line in anthem.iter() {
|
||||
v.push(*line);
|
||||
}
|
||||
}
|
||||
let freqs = frequency::frequency(&v[..], 3);
|
||||
assert_eq!(freqs.get(&'a'), Some(&49));
|
||||
assert_eq!(freqs.get(&'t'), Some(&56));
|
||||
assert_eq!(freqs.get(&'ü'), Some(&2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_integer_multiple_of_threads() {
|
||||
let v = vec!["abc"; 999];
|
||||
let mut hm = HashMap::new();
|
||||
hm.insert('a', 999);
|
||||
hm.insert('b', 999);
|
||||
hm.insert('c', 999);
|
||||
assert_eq!(frequency::frequency(&v[..], 4), hm);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn large_texts() {
|
||||
let expected: HashMap<char, usize> = [
|
||||
('a', 845),
|
||||
('b', 155),
|
||||
('c', 278),
|
||||
('d', 359),
|
||||
('e', 1143),
|
||||
('f', 222),
|
||||
('g', 187),
|
||||
('h', 507),
|
||||
('i', 791),
|
||||
('j', 12),
|
||||
('k', 67),
|
||||
('l', 423),
|
||||
('m', 288),
|
||||
('n', 833),
|
||||
('o', 791),
|
||||
('p', 197),
|
||||
('q', 8),
|
||||
('r', 432),
|
||||
('s', 700),
|
||||
('t', 1043),
|
||||
('u', 325),
|
||||
('v', 111),
|
||||
('w', 223),
|
||||
('x', 7),
|
||||
('y', 251),
|
||||
]
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
assert_eq!(frequency::frequency(&DOSTOEVSKY, 4), expected);
|
||||
}
|
||||
|
||||
// Poem by Friedrich Schiller. The corresponding music is the European Anthem.
|
||||
const ODE_AN_DIE_FREUDE: [&str; 8] = [
|
||||
"Freude schöner Götterfunken",
|
||||
"Tochter aus Elysium,",
|
||||
"Wir betreten feuertrunken,",
|
||||
"Himmlische, dein Heiligtum!",
|
||||
"Deine Zauber binden wieder",
|
||||
"Was die Mode streng geteilt;",
|
||||
"Alle Menschen werden Brüder,",
|
||||
"Wo dein sanfter Flügel weilt.",
|
||||
];
|
||||
|
||||
// Dutch national anthem
|
||||
const WILHELMUS: [&str; 8] = [
|
||||
"Wilhelmus van Nassouwe",
|
||||
"ben ik, van Duitsen bloed,",
|
||||
"den vaderland getrouwe",
|
||||
"blijf ik tot in den dood.",
|
||||
"Een Prinse van Oranje",
|
||||
"ben ik, vrij, onverveerd,",
|
||||
"den Koning van Hispanje",
|
||||
"heb ik altijd geëerd.",
|
||||
];
|
||||
|
||||
// American national anthem
|
||||
const STAR_SPANGLED_BANNER: [&str; 8] = [
|
||||
"O say can you see by the dawn's early light,",
|
||||
"What so proudly we hailed at the twilight's last gleaming,",
|
||||
"Whose broad stripes and bright stars through the perilous fight,",
|
||||
"O'er the ramparts we watched, were so gallantly streaming?",
|
||||
"And the rockets' red glare, the bombs bursting in air,",
|
||||
"Gave proof through the night that our flag was still there;",
|
||||
"O say does that star-spangled banner yet wave,",
|
||||
"O'er the land of the free and the home of the brave?",
|
||||
];
|
||||
|
||||
const DOSTOEVSKY: [&str; 4] = [
|
||||
r#"
|
||||
I am a sick man.... I am a spiteful man. I am an unattractive man.
|
||||
I believe my liver is diseased. However, I know nothing at all about my disease, and do not
|
||||
know for certain what ails me. I don't consult a doctor for it,
|
||||
and never have, though I have a respect for medicine and doctors.
|
||||
Besides, I am extremely superstitious, sufficiently so to respect medicine,
|
||||
anyway (I am well-educated enough not to be superstitious, but I am superstitious).
|
||||
No, I refuse to consult a doctor from spite.
|
||||
That you probably will not understand. Well, I understand it, though.
|
||||
Of course, I can't explain who it is precisely that I am mortifying in this case by my spite:
|
||||
I am perfectly well aware that I cannot "pay out" the doctors by not consulting them;
|
||||
I know better than anyone that by all this I am only injuring myself and no one else.
|
||||
But still, if I don't consult a doctor it is from spite.
|
||||
My liver is bad, well - let it get worse!
|
||||
I have been going on like that for a long time - twenty years. Now I am forty.
|
||||
I used to be in the government service, but am no longer.
|
||||
I was a spiteful official. I was rude and took pleasure in being so.
|
||||
I did not take bribes, you see, so I was bound to find a recompense in that, at least.
|
||||
(A poor jest, but I will not scratch it out. I wrote it thinking it would sound very witty;
|
||||
but now that I have seen myself that I only wanted to show off in a despicable way -
|
||||
I will not scratch it out on purpose!) When petitioners used to come for
|
||||
information to the table at which I sat, I used to grind my teeth at them,
|
||||
and felt intense enjoyment when I succeeded in making anybody unhappy.
|
||||
I almost did succeed. For the most part they were all timid people - of course,
|
||||
they were petitioners. But of the uppish ones there was one officer in particular
|
||||
I could not endure. He simply would not be humble, and clanked his sword in a disgusting way.
|
||||
I carried on a feud with him for eighteen months over that sword. At last I got the better of him.
|
||||
He left off clanking it. That happened in my youth, though. But do you know,
|
||||
gentlemen, what was the chief point about my spite? Why, the whole point,
|
||||
the real sting of it lay in the fact that continually, even in the moment of the acutest spleen,
|
||||
I was inwardly conscious with shame that I was not only not a spiteful but not even an embittered man,
|
||||
that I was simply scaring sparrows at random and amusing myself by it.
|
||||
I might foam at the mouth, but bring me a doll to play with, give me a cup of tea with sugar in it,
|
||||
and maybe I should be appeased. I might even be genuinely touched,
|
||||
though probably I should grind my teeth at myself afterwards and lie awake at night with shame for
|
||||
months after. That was my way. I was lying when I said just now that I was a spiteful official.
|
||||
I was lying from spite. I was simply amusing myself with the petitioners and with the officer,
|
||||
and in reality I never could become spiteful. I was conscious every moment in myself of many,
|
||||
very many elements absolutely opposite to that. I felt them positively swarming in me,
|
||||
these opposite elements. I knew that they had been swarming in me all my life and craving some outlet from me,
|
||||
but I would not let them, would not let them, purposely would not let them come out.
|
||||
They tormented me till I was ashamed: they drove me to convulsions and - sickened me, at last,
|
||||
how they sickened me!
|
||||
"#,
|
||||
r#"
|
||||
Gentlemen, I am joking, and I know myself that my jokes are not brilliant,
|
||||
but you know one can take everything as a joke. I am, perhaps, jesting against the grain.
|
||||
Gentlemen, I am tormented by questions; answer them for me. You, for instance, want to cure men of their
|
||||
old habits and reform their will in accordance with science and good sense.
|
||||
But how do you know, not only that it is possible, but also that it is
|
||||
desirable to reform man in that way? And what leads you to the conclusion that man's
|
||||
inclinations need reforming? In short, how do you know that such a reformation will be a benefit to man?
|
||||
And to go to the root of the matter, why are you so positively convinced that not to act against
|
||||
his real normal interests guaranteed by the conclusions of reason and arithmetic is certainly always
|
||||
advantageous for man and must always be a law for mankind? So far, you know,
|
||||
this is only your supposition. It may be the law of logic, but not the law of humanity.
|
||||
You think, gentlemen, perhaps that I am mad? Allow me to defend myself. I agree that man
|
||||
is pre-eminently a creative animal, predestined to strive consciously for an object and to engage in engineering -
|
||||
that is, incessantly and eternally to make new roads, wherever
|
||||
they may lead. But the reason why he wants sometimes to go off at a tangent may just be that he is
|
||||
predestined to make the road, and perhaps, too, that however stupid the "direct"
|
||||
practical man may be, the thought sometimes will occur to him that the road almost always does lead
|
||||
somewhere, and that the destination it leads to is less important than the process
|
||||
of making it, and that the chief thing is to save the well-conducted child from despising engineering,
|
||||
and so giving way to the fatal idleness, which, as we all know,
|
||||
is the mother of all the vices. Man likes to make roads and to create, that is a fact beyond dispute.
|
||||
But why has he such a passionate love for destruction and chaos also?
|
||||
Tell me that! But on that point I want to say a couple of words myself. May it not be that he loves
|
||||
chaos and destruction (there can be no disputing that he does sometimes love it)
|
||||
because he is instinctively afraid of attaining his object and completing the edifice he is constructing?
|
||||
Who knows, perhaps he only loves that edifice from a distance, and is by no means
|
||||
in love with it at close quarters; perhaps he only loves building it and does not want to live in it,
|
||||
but will leave it, when completed, for the use of les animaux domestiques -
|
||||
such as the ants, the sheep, and so on. Now the ants have quite a different taste.
|
||||
They have a marvellous edifice of that pattern which endures for ever - the ant-heap.
|
||||
With the ant-heap the respectable race of ants began and with the ant-heap they will probably end,
|
||||
which does the greatest credit to their perseverance and good sense. But man is a frivolous and
|
||||
incongruous creature, and perhaps, like a chess player, loves the process of the game, not the end of it.
|
||||
And who knows (there is no saying with certainty), perhaps the only goal on earth
|
||||
to which mankind is striving lies in this incessant process of attaining, in other words,
|
||||
in life itself, and not in the thing to be attained, which must always be expressed as a formula,
|
||||
as positive as twice two makes four, and such positiveness is not life, gentlemen,
|
||||
but is the beginning of death.
|
||||
"#,
|
||||
r#"
|
||||
But these are all golden dreams. Oh, tell me, who was it first announced,
|
||||
who was it first proclaimed, that man only does nasty things because he does not know his own interests;
|
||||
and that if he were enlightened, if his eyes were opened to his real normal interests,
|
||||
man would at once cease to do nasty things, would at once become good and noble because,
|
||||
being enlightened and understanding his real advantage, he would see his own advantage in the
|
||||
good and nothing else, and we all know that not one man can, consciously, act against his own interests,
|
||||
consequently, so to say, through necessity, he would begin doing good? Oh, the babe! Oh, the pure,
|
||||
innocent child! Why, in the first place, when in all these thousands of years has there been a time
|
||||
when man has acted only from his own interest? What is to be done with the millions of facts that bear
|
||||
witness that men, consciously, that is fully understanding their real interests, have left them in the
|
||||
background and have rushed headlong on another path, to meet peril and danger,
|
||||
compelled to this course by nobody and by nothing, but, as it were, simply disliking the beaten track,
|
||||
and have obstinately, wilfully, struck out another difficult, absurd way, seeking it almost in the darkness.
|
||||
So, I suppose, this obstinacy and perversity were pleasanter to them than any advantage....
|
||||
Advantage! What is advantage? And will you take it upon yourself to define with perfect accuracy in what the
|
||||
advantage of man consists? And what if it so happens that a man's advantage, sometimes, not only may,
|
||||
but even must, consist in his desiring in certain cases what is harmful to himself and not advantageous.
|
||||
And if so, if there can be such a case, the whole principle falls into dust. What do you think -
|
||||
are there such cases? You laugh; laugh away, gentlemen, but only answer me: have man's advantages been
|
||||
reckoned up with perfect certainty? Are there not some which not only have not been included but cannot
|
||||
possibly be included under any classification? You see, you gentlemen have, to the best of my knowledge,
|
||||
taken your whole register of human advantages from the averages of statistical figures and
|
||||
politico-economical formulas. Your advantages are prosperity, wealth, freedom, peace - and so on, and so on.
|
||||
So that the man who should, for instance, go openly and knowingly in opposition to all that list would to your thinking,
|
||||
and indeed mine, too, of course, be an obscurantist or an absolute madman: would not he? But, you know, this is
|
||||
what is surprising: why does it so happen that all these statisticians, sages and lovers of humanity,
|
||||
when they reckon up human advantages invariably leave out one? They don't even take it into their reckoning
|
||||
in the form in which it should be taken, and the whole reckoning depends upon that. It would be no greater matter,
|
||||
they would simply have to take it, this advantage, and add it to the list. But the trouble is, that this strange
|
||||
advantage does not fall under any classification and is not in place in any list. I have a friend for instance ...
|
||||
Ech! gentlemen, but of course he is your friend, too; and indeed there is no one, no one to whom he is not a friend!
|
||||
"#,
|
||||
r#"
|
||||
Yes, but here I come to a stop! Gentlemen, you must excuse me for being over-philosophical;
|
||||
it's the result of forty years underground! Allow me to indulge my fancy. You see, gentlemen, reason is an excellent thing,
|
||||
there's no disputing that, but reason is nothing but reason and satisfies only the rational side of man's nature,
|
||||
while will is a manifestation of the whole life, that is, of the whole human life including reason and all the impulses.
|
||||
And although our life, in this manifestation of it, is often worthless, yet it is life and not simply extracting square roots.
|
||||
Here I, for instance, quite naturally want to live, in order to satisfy all my capacities for life, and not simply my capacity
|
||||
for reasoning, that is, not simply one twentieth of my capacity for life. What does reason know? Reason only knows what it has
|
||||
succeeded in learning (some things, perhaps, it will never learn; this is a poor comfort, but why not say so frankly?)
|
||||
and human nature acts as a whole, with everything that is in it, consciously or unconsciously, and, even it if goes wrong, it lives.
|
||||
I suspect, gentlemen, that you are looking at me with compassion; you tell me again that an enlightened and developed man,
|
||||
such, in short, as the future man will be, cannot consciously desire anything disadvantageous to himself, that that can be proved mathematically.
|
||||
I thoroughly agree, it can - by mathematics. But I repeat for the hundredth time, there is one case, one only, when man may consciously, purposely,
|
||||
desire what is injurious to himself, what is stupid, very stupid - simply in order to have the right to desire for himself even what is very stupid
|
||||
and not to be bound by an obligation to desire only what is sensible. Of course, this very stupid thing, this caprice of ours, may be in reality,
|
||||
gentlemen, more advantageous for us than anything else on earth, especially in certain cases. And in particular it may be more advantageous than
|
||||
any advantage even when it does us obvious harm, and contradicts the soundest conclusions of our reason concerning our advantage -
|
||||
for in any circumstances it preserves for us what is most precious and most important - that is, our personality, our individuality.
|
||||
Some, you see, maintain that this really is the most precious thing for mankind; choice can, of course, if it chooses, be in agreement
|
||||
with reason; and especially if this be not abused but kept within bounds. It is profitable and some- times even praiseworthy.
|
||||
But very often, and even most often, choice is utterly and stubbornly opposed to reason ... and ... and ... do you know that that,
|
||||
too, is profitable, sometimes even praiseworthy? Gentlemen, let us suppose that man is not stupid. (Indeed one cannot refuse to suppose that,
|
||||
if only from the one consideration, that, if man is stupid, then who is wise?) But if he is not stupid, he is monstrously ungrateful!
|
||||
Phenomenally ungrateful. In fact, I believe that the best definition of man is the ungrateful biped. But that is not all, that is not his worst defect;
|
||||
his worst defect is his perpetual moral obliquity, perpetual - from the days of the Flood to the Schleswig-Holstein period.
|
||||
"#,
|
||||
];
|
||||
Loading…
Add table
Add a link
Reference in a new issue